/src/wireshark/epan/dissectors/packet-ismacryp.c
Line | Count | Source |
1 | | /* packet-ismacryp.c |
2 | | * ISMACryp 1.1 & 2.0 protocol as defined in ISMA Encryption and Authentication see http://www.isma.tv |
3 | | * |
4 | | * David Castleford, Orange Labs / France Telecom R&D |
5 | | * March 2009 |
6 | | * |
7 | | * Wireshark - Network traffic analyzer |
8 | | * By Gerald Combs <gerald@wireshark.org> |
9 | | * Copyright 1998 Gerald Combs |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | */ |
13 | | |
14 | | /* TODO: get ISMACryp parameters automatically from SDP info, |
15 | | * if present (typically sent via SAP/SDP), |
16 | | * rather than having manual insertion via preferences |
17 | | * TODO: perhaps better check coherence of certain information? |
18 | | */ |
19 | | #include "config.h" |
20 | | |
21 | | #include <epan/packet.h> |
22 | | #include <epan/prefs.h> |
23 | | #include <epan/unit_strings.h> |
24 | | |
25 | | void proto_register_ismacryp(void); |
26 | | void proto_reg_handoff_ismacryp(void); |
27 | | |
28 | | static dissector_handle_t ismacryp_handle; |
29 | | static dissector_handle_t ismacryp_v11_handle; |
30 | | static dissector_handle_t ismacryp_v20_handle; |
31 | | |
32 | | /* keeps track of current position in buffer in terms of bit and byte offset */ |
33 | | typedef struct Toffset_struct |
34 | | { |
35 | | int offset_bytes; |
36 | | uint8_t offset_bits; |
37 | | |
38 | | } offset_struct; |
39 | | |
40 | | static void dissect_ismacryp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int ismacryp_version); |
41 | | static offset_struct* dissect_auheader( tvbuff_t *tvb, offset_struct *poffset, packet_info *pinfo, proto_tree *tree, unsigned set_version ); |
42 | | static void add_bits(offset_struct* poffset, int len_bits); |
43 | | |
44 | | #define PROTO_TAG_ISMACRYP "ISMACRYP" |
45 | 14 | #define PROTO_TAG_ISMACRYP_11 "ISMACryp_11" |
46 | 14 | #define PROTO_TAG_ISMACRYP_20 "ISMACryp_20" |
47 | 14 | #define V11 11 |
48 | 14 | #define V20 20 |
49 | 14 | #define AAC_HBR_MODE 0 |
50 | 14 | #define MPEG4_VIDEO_MODE 1 |
51 | 14 | #define AVC_VIDEO_MODE 2 |
52 | | /* #define USERMODE 3 */ |
53 | | #define DEFAULT_SELECTIVE_ENCRYPTION true |
54 | | #define DEFAULT_SLICE_INDICATION false |
55 | | #define DEFAULT_PADDING_INDICATION false |
56 | | #define DEFAULT_IV_LENGTH 4 |
57 | | #define DEFAULT_DELTA_IV_LENGTH 0 |
58 | | #define DEFAULT_KEY_INDICATOR_LENGTH 0 |
59 | | #define DEFAULT_KEY_INDICATOR_PER_AU false |
60 | 0 | #define AU_HEADERS_LENGTH_SIZE 2 /* size in bytes */ |
61 | | #define DEFAULT_AU_SIZE_LENGTH 0 |
62 | | #define DEFAULT_AU_INDEX_LENGTH 0 |
63 | | #define DEFAULT_AU_INDEX_DELTA_LENGTH 0 |
64 | | #define DEFAULT_CTS_DELTA_LENGTH 0 |
65 | | #define DEFAULT_DTS_DELTA_LENGTH 0 |
66 | | #define DEFAULT_RANDOM_ACCESS_INDICATION false |
67 | | #define DEFAULT_STREAM_STATE_INDICATION 0 |
68 | | |
69 | | /* Wireshark ID of the ISMACRYP protocol */ |
70 | | static int proto_ismacryp; |
71 | | static int proto_ismacryp_v11; |
72 | | static int proto_ismacryp_v20; |
73 | | |
74 | | /* parameters set in preferences */ |
75 | | static unsigned pref_au_size_length = DEFAULT_AU_SIZE_LENGTH; /* default Au size length */ |
76 | | static unsigned pref_au_index_length = DEFAULT_AU_INDEX_LENGTH; /* default Au index length */ |
77 | | static unsigned pref_au_index_delta_length = DEFAULT_AU_INDEX_DELTA_LENGTH; /* default Au index delta length */ |
78 | | static unsigned pref_cts_delta_length = DEFAULT_CTS_DELTA_LENGTH; /* default CTS delta length */ |
79 | | static unsigned pref_dts_delta_length = DEFAULT_DTS_DELTA_LENGTH; /* default DTS delta length */ |
80 | | static bool pref_random_access_indication = DEFAULT_RANDOM_ACCESS_INDICATION; /* default random access indication */ |
81 | | static unsigned pref_stream_state_indication = DEFAULT_STREAM_STATE_INDICATION; /* default stream state indication */ |
82 | | static int version_type = V11; /* default to ISMACryp 1.1 */ |
83 | | static int mode = AVC_VIDEO_MODE; /* default codec mode */ |
84 | | static bool selective_encryption = DEFAULT_SELECTIVE_ENCRYPTION; /* default selective encryption flag */ |
85 | | static bool slice_indication = DEFAULT_SLICE_INDICATION; /* default slice indication */ |
86 | | static bool padding_indication = DEFAULT_PADDING_INDICATION; /* default padding indication */ |
87 | | static unsigned key_indicator_length = DEFAULT_KEY_INDICATOR_LENGTH; /* default key indicator length */ |
88 | | static bool key_indicator_per_au_flag = DEFAULT_KEY_INDICATOR_PER_AU; /* default key indicator per au */ |
89 | | static unsigned iv_length = DEFAULT_IV_LENGTH; /* default IV length */ |
90 | | static unsigned delta_iv_length = DEFAULT_DELTA_IV_LENGTH; /* default delta IV length */ |
91 | | static bool pref_user_mode; /* preference user mode instead of RFC3640 mode? */ |
92 | | static bool override_flag; /* override use of RTP payload type to deduce ISMACryp version */ |
93 | | |
94 | | /* */ |
95 | | |
96 | | static unsigned au_size_length = DEFAULT_AU_SIZE_LENGTH; /* default Au size length */ |
97 | | static unsigned au_index_length = DEFAULT_AU_INDEX_LENGTH; /* default Au index length */ |
98 | | static unsigned au_index_delta_length = DEFAULT_AU_INDEX_DELTA_LENGTH; /* default Au index delta length */ |
99 | | static unsigned cts_delta_length = DEFAULT_CTS_DELTA_LENGTH; /* default CTS delta length */ |
100 | | static unsigned dts_delta_length = DEFAULT_DTS_DELTA_LENGTH; /* default DTS delta length */ |
101 | | static bool random_access_indication = DEFAULT_RANDOM_ACCESS_INDICATION; /* default random access indication */ |
102 | | static unsigned stream_state_indication = DEFAULT_STREAM_STATE_INDICATION; /* default stream state indication */ |
103 | | static bool user_mode; /* selected user mode instead of RFC3640 mode? */ |
104 | | |
105 | | /*static const value_string messagetypenames[] = {}; */ |
106 | | |
107 | | /* ismacryp Parameter Types */ |
108 | | /*static const value_string parametertypenames[] = {}; */ |
109 | | static const value_string modetypenames[] = { |
110 | | { AAC_HBR_MODE, "aac-hbr" }, |
111 | | { MPEG4_VIDEO_MODE, "mpeg4-video" }, |
112 | | { AVC_VIDEO_MODE, "avc-video" }, |
113 | | { 0, NULL} |
114 | | }; |
115 | | /* The following hf_* variables are used to hold the Wireshark IDs of |
116 | | * our header fields; they are filled out when we call |
117 | | * proto_register_field_array() in proto_register_ismacryp() |
118 | | */ |
119 | | /** Kts attempt at defining the protocol */ |
120 | | /* static int hf_ismacryp; */ |
121 | | static int hf_ismacryp_header; |
122 | | static int hf_ismacryp_au_headers_length; |
123 | | /* static int hf_ismacryp_header_length; */ |
124 | | static int hf_ismacryp_header_byte; |
125 | | /* static int hf_ismacryp_version; */ |
126 | | /* static int hf_ismacryp_length; */ |
127 | | /* static int hf_ismacryp_message_type; */ |
128 | | /* static int hf_ismacryp_message_length; */ |
129 | | static int hf_ismacryp_message; |
130 | | /* static int hf_ismacryp_parameter; */ |
131 | | /* static int hf_ismacryp_parameter_type; */ |
132 | | /* static int hf_ismacryp_parameter_length; */ |
133 | | /* static int hf_ismacryp_parameter_value; */ |
134 | | static int hf_ismacryp_iv; |
135 | | static int hf_ismacryp_delta_iv; |
136 | | static int hf_ismacryp_key_indicator; |
137 | | /* static int hf_ismacryp_delta_iv_length; */ |
138 | | static int hf_ismacryp_au_size; |
139 | | static int hf_ismacryp_au_index; |
140 | | static int hf_ismacryp_au_index_delta; |
141 | | static int hf_ismacryp_cts_delta; |
142 | | static int hf_ismacryp_cts_flag; |
143 | | static int hf_ismacryp_dts_flag; |
144 | | static int hf_ismacryp_dts_delta; |
145 | | static int hf_ismacryp_rap_flag; |
146 | | static int hf_ismacryp_au_is_encrypted; |
147 | | static int hf_ismacryp_slice_start; |
148 | | static int hf_ismacryp_slice_end; |
149 | | static int hf_ismacryp_padding_bitcount; |
150 | | static int hf_ismacryp_padding; |
151 | | static int hf_ismacryp_reserved_bits; |
152 | | static int hf_ismacryp_unused_bits; |
153 | | static int hf_ismacryp_stream_state; |
154 | | |
155 | | /* These are the ids of the subtrees that we may be creating */ |
156 | | static int ett_ismacryp; |
157 | | static int ett_ismacryp_header; |
158 | | static int ett_ismacryp_header_byte; |
159 | | static int ett_ismacryp_message; |
160 | | |
161 | | /* Informative tree structure is shown here: |
162 | | * TREE - |
163 | | * AU Headers Length (2 bytes) - total length of AU header(s) |
164 | | * - HEADER1 |
165 | | * HEADER BYTE (if present - 1 byte) |
166 | | * -AU_is_encrypted (1 bit) |
167 | | * -Slice_start (1 bit) |
168 | | * -Slice_end (1 bit) |
169 | | * -Padding_bitcount (3 bits) |
170 | | * -Reserved (2 bits) |
171 | | * IV (variable length) |
172 | | * Key Indicator (variable length) |
173 | | * AU size (if present - variable length) |
174 | | * AU index (if present - variable length) |
175 | | * CTS delta (if present - variable length) |
176 | | * DTS delta (if present - variable length) |
177 | | * RAP flag (if present - 1 bit) |
178 | | * Stream State Indication (if present - variable length) |
179 | | * - HEADER2 if 2nd header present (depends on AU headers length) |
180 | | * Header Byte (if present - 1 byte) |
181 | | * -AU_is_encrypted (1 bit) |
182 | | * -Slice_start (1 bit) |
183 | | * -Slice_end (1 bit) |
184 | | * -Padding_bitcount (3 bits) |
185 | | * -Reserved (2 bits) |
186 | | * IV (variable length) |
187 | | * Key Indicator (variable length) |
188 | | * AU size (if present - variable length) |
189 | | * AU index delta(if present - variable length) |
190 | | * CTS delta (if present - variable length) |
191 | | * DTS delta (if present - variable length) |
192 | | * RAP flag (if present - 1 bit) |
193 | | * Stream State Indication (if present - variable length) |
194 | | * - more HEADERS if present |
195 | | * - MESSAGE |
196 | | * encrypted AU |
197 | | * End informative tree structure |
198 | | */ |
199 | | |
200 | | /* Note that check coherence of total AU headers length and that calculated from size of parameters defined by default or preferences. |
201 | | * These are found in SDP and vary e.g. between audio and video and depend on ISMACryp encoding parameters |
202 | | * hence if these values are incorrect displayed values will be strange and can see errors |
203 | | * this could be improved of course |
204 | | */ |
205 | | |
206 | | /* dissect_ismacryp_v11 gets called if rtp_dyn_payload_type = "enc-mpeg4-generic" i.e. is set via SDP */ |
207 | | static int dissect_ismacryp_v11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
208 | 0 | { |
209 | | /* display ISMACryp version */ |
210 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_11); |
211 | | |
212 | | /* display RTP payload type */ |
213 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "(PT=enc-mpeg4-generic)"); |
214 | |
|
215 | 0 | dissect_ismacryp_common( tvb, pinfo, tree, V11); |
216 | 0 | return tvb_captured_length(tvb); |
217 | 0 | } |
218 | | |
219 | | /* dissect_ismacryp_v20 gets called if rtp_dyn_payload_type = "enc-isoff-generic" i.e. is set via SDP */ |
220 | | static int dissect_ismacryp_v20(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
221 | 0 | { |
222 | | /* display ISMACryp version */ |
223 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_20); |
224 | | |
225 | | /* display RTP payload type */ |
226 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "(PT=enc-isoff-generic)"); |
227 | |
|
228 | 0 | dissect_ismacryp_common( tvb, pinfo, tree, V20); |
229 | 0 | return tvb_captured_length(tvb); |
230 | 0 | } |
231 | | |
232 | | static int dissect_ismacryp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
233 | 0 | { |
234 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Manual version"); |
235 | 0 | dissect_ismacryp_common( tvb, pinfo, tree, version_type); /* Unknown version type: Use preference */ |
236 | 0 | return tvb_captured_length(tvb); |
237 | 0 | } |
238 | | |
239 | | static void dissect_ismacryp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int ismacryp_version) |
240 | 0 | { |
241 | 0 | unsigned set_version; /* ISMACryp version used during dissection */ |
242 | 0 | proto_item *ismacryp_item; |
243 | 0 | proto_tree *ismacryp_tree; |
244 | 0 | proto_tree *ismacryp_message_tree; |
245 | | |
246 | | /* select and display ISMACryp version */ |
247 | 0 | if ((ismacryp_version != version_type) && override_flag) { |
248 | | /* override -> use manual preference setting */ |
249 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " Manual version"); |
250 | 0 | set_version = version_type; /* set to preference value */ |
251 | 0 | } |
252 | 0 | else { |
253 | 0 | set_version = ismacryp_version; |
254 | 0 | } |
255 | |
|
256 | 0 | if (set_version == V11) { |
257 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_11); |
258 | | /* display mode */ |
259 | 0 | if (pref_user_mode == false) { |
260 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(mode, modetypenames, "user mode")); |
261 | 0 | } else { |
262 | 0 | col_append_str(pinfo->cinfo, COL_INFO, ", user mode"); |
263 | 0 | } |
264 | 0 | user_mode = pref_user_mode; |
265 | 0 | } |
266 | 0 | if (set_version == V20) { |
267 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_20); |
268 | 0 | user_mode = true; |
269 | | /* display mode */ |
270 | 0 | col_append_str(pinfo->cinfo, COL_INFO, ", user mode"); |
271 | 0 | } |
272 | | /* select correct AU values depending on version & selected mode in preferences menu if not in user_mode */ |
273 | 0 | if (user_mode == true) { /* use values set in preference menu */ |
274 | 0 | au_size_length = pref_au_size_length; |
275 | 0 | au_index_length = pref_au_index_length; |
276 | 0 | au_index_delta_length = pref_au_index_delta_length; |
277 | 0 | cts_delta_length = pref_cts_delta_length; |
278 | 0 | dts_delta_length = pref_dts_delta_length; |
279 | 0 | random_access_indication = pref_random_access_indication; |
280 | 0 | stream_state_indication = pref_stream_state_indication; |
281 | 0 | } /* end if user_mode == true */ |
282 | 0 | if (user_mode == false) { |
283 | 0 | switch (mode) { |
284 | 0 | case AAC_HBR_MODE: |
285 | 0 | au_size_length = 13; |
286 | 0 | au_index_length = 3; |
287 | 0 | au_index_delta_length = 3; |
288 | 0 | cts_delta_length = 0; |
289 | 0 | dts_delta_length = 0; |
290 | 0 | random_access_indication = false; |
291 | 0 | stream_state_indication = 0; |
292 | 0 | break; |
293 | 0 | case MPEG4_VIDEO_MODE: |
294 | 0 | au_size_length = 0; |
295 | 0 | au_index_length = 0; |
296 | 0 | au_index_delta_length = 0; |
297 | 0 | cts_delta_length = 0; |
298 | 0 | dts_delta_length = 22; |
299 | 0 | random_access_indication = true; |
300 | 0 | stream_state_indication = 0; |
301 | 0 | break; |
302 | 0 | case AVC_VIDEO_MODE: |
303 | 0 | au_size_length = 0; |
304 | 0 | au_index_length = 0; |
305 | 0 | au_index_delta_length = 0; |
306 | 0 | cts_delta_length = 0; |
307 | 0 | dts_delta_length = 22; |
308 | 0 | random_access_indication = true; |
309 | 0 | stream_state_indication = 0; |
310 | 0 | break; |
311 | 0 | default: |
312 | 0 | DISSECTOR_ASSERT_NOT_REACHED(); |
313 | 0 | break; |
314 | 0 | } /* end switch */ |
315 | 0 | } /* end if user_mode == false */ |
316 | | |
317 | | /* navigate through buffer */ |
318 | 0 | { |
319 | 0 | uint16_t au_headers_length; /* total length of AU headers */ |
320 | 0 | uint16_t totalbits; /* keeps track of total number of AU header bits treated (used to determine end of AU headers) */ |
321 | 0 | int deltabits; /* keeps track of extra bits per AU header treated (used to determine end of AU headers ) */ |
322 | 0 | offset_struct s_offset; |
323 | 0 | offset_struct* poffset; |
324 | 0 | uint16_t nbmessage_bytes; /*nb of message data bytes */ |
325 | 0 | s_offset.offset_bytes = 0; /* initialise byte offset */ |
326 | 0 | s_offset.offset_bits = 0; /* initialise bit offset */ |
327 | 0 | poffset = &s_offset; |
328 | |
|
329 | 0 | ismacryp_item = proto_tree_add_item(tree, proto_ismacryp, tvb, 0, -1, ENC_NA); |
330 | 0 | ismacryp_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp); |
331 | 0 | proto_item_append_text(tree, ", %s", "ismacryp packet"); /* add text to tree */ |
332 | | |
333 | | /* ismacryp_tree analysis */ |
334 | | /* get total length of AU headers (first 2 bytes) */ |
335 | 0 | proto_tree_add_item(ismacryp_tree, hf_ismacryp_au_headers_length, |
336 | 0 | tvb, poffset->offset_bytes, AU_HEADERS_LENGTH_SIZE, ENC_BIG_ENDIAN ); |
337 | 0 | au_headers_length = tvb_get_ntohs(tvb, poffset->offset_bytes); /* 2 byte au headers length */ |
338 | 0 | poffset->offset_bytes += AU_HEADERS_LENGTH_SIZE; |
339 | | /* ADD HEADER(S) BRANCH */ |
340 | | |
341 | | /* AU Header loop */ |
342 | 0 | totalbits = (poffset->offset_bytes*8) + poffset->offset_bits; |
343 | 0 | deltabits = 1; |
344 | 0 | while( ((totalbits - 8*AU_HEADERS_LENGTH_SIZE)<au_headers_length) && deltabits != 0 ) /* subtract AU headers length bits*/ |
345 | 0 | { |
346 | 0 | poffset = dissect_auheader( tvb, poffset, pinfo, ismacryp_tree, set_version); |
347 | 0 | deltabits = (poffset->offset_bytes*8) + poffset->offset_bits - totalbits; /* if zero this means no actual AU header so exit while loop */ |
348 | 0 | totalbits += deltabits; |
349 | 0 | } |
350 | | /* reached end of AU Header(s) */ |
351 | | /* sanity check if actual total AU headers length in bits i.e. totalbits is */ |
352 | | /* the same as expected AU headers length from 2 bytes at start of buffer */ |
353 | 0 | if ( (totalbits - 8*AU_HEADERS_LENGTH_SIZE) != au_headers_length) /* something wrong */ |
354 | 0 | { |
355 | 0 | proto_item_append_text(ismacryp_item, |
356 | 0 | " Error - expected total AU headers size (%d bits) " |
357 | 0 | "does not match calculated size (%d bits) - check parameters!", |
358 | 0 | au_headers_length, (totalbits - 8*AU_HEADERS_LENGTH_SIZE)); |
359 | 0 | } |
360 | | /* add padding if need to byte align */ |
361 | 0 | if (poffset->offset_bits != 0) |
362 | 0 | { |
363 | 0 | uint16_t totalbit_offset; /* total offset in bits*/ |
364 | 0 | int nbpadding_bits; /* number of padding bits*/ |
365 | 0 | totalbit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
366 | 0 | nbpadding_bits = (8 - poffset->offset_bits); /* number of padding bits for byte alignment */ |
367 | 0 | ismacryp_item = proto_tree_add_bits_item(ismacryp_tree, hf_ismacryp_padding, |
368 | 0 | tvb, totalbit_offset, nbpadding_bits , ENC_BIG_ENDIAN); /* padding bits */ |
369 | 0 | proto_item_append_text(ismacryp_item, ": Length=%d bits", nbpadding_bits); /* add padding info */ |
370 | 0 | add_bits(poffset, nbpadding_bits); |
371 | 0 | } |
372 | | /* ADD MESSAGE BRANCH */ |
373 | 0 | ismacryp_item = proto_tree_add_item( ismacryp_tree, hf_ismacryp_message, |
374 | 0 | tvb, poffset->offset_bytes, -1, ENC_NA ); |
375 | 0 | ismacryp_message_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_message); |
376 | 0 | proto_item_append_text(ismacryp_item, ", %s", "Encrypted data"); /* add text to Message tree */ |
377 | 0 | nbmessage_bytes = tvb_reported_length_remaining(tvb, poffset->offset_bytes); |
378 | 0 | proto_item_append_text(ismacryp_item, ", Length= %d bytes", nbmessage_bytes ); /* add length of message */ |
379 | | |
380 | | /* ismacryp message tree analysis (encrypted AUs) */ |
381 | 0 | if (ismacryp_message_tree) |
382 | 0 | { |
383 | 0 | poffset->offset_bytes += nbmessage_bytes; /* */ |
384 | 0 | } |
385 | 0 | } |
386 | 0 | } |
387 | | /* AU Header dissection */ |
388 | | static offset_struct* dissect_auheader( tvbuff_t *tvb, offset_struct *poffset, packet_info *pinfo, proto_tree *ismacryp_tree, unsigned set_version ) |
389 | 0 | { |
390 | 0 | proto_item *ismacryp_item; |
391 | 0 | proto_tree *ismacryp_header_tree; |
392 | 0 | proto_tree *ismacryp_header_byte_tree; |
393 | |
|
394 | 0 | uint16_t header_len_bytes = 0; /* total length of non-first AU header in bytes (rounded up) */ |
395 | 0 | int header_len = 0; /* length of AU headers in bits */ |
396 | 0 | int cts_flag =0; |
397 | 0 | int dts_flag =0; |
398 | 0 | bool first_au_flag = false; |
399 | 0 | int bit_offset = 0; |
400 | | |
401 | | /*first determine total AU header length */ |
402 | | /* calculate each AU header length in bits first */ |
403 | 0 | switch (set_version) { |
404 | 0 | case V11: |
405 | 0 | if (selective_encryption) |
406 | 0 | header_len += 8; /* add one byte to header length */ |
407 | 0 | break; |
408 | 0 | case V20: |
409 | 0 | if (selective_encryption || slice_indication || padding_indication) |
410 | 0 | header_len += 8; /* add one byte to header length */ |
411 | 0 | break; |
412 | 0 | default: |
413 | 0 | DISSECTOR_ASSERT_NOT_REACHED(); |
414 | 0 | break; |
415 | 0 | } /* end switch */ |
416 | 0 | header_len += au_size_length; /* add au size length */ |
417 | |
|
418 | 0 | if (poffset->offset_bytes == AU_HEADERS_LENGTH_SIZE) { /*first AU */ |
419 | 0 | header_len += 8*(iv_length); /* add IV length */ |
420 | 0 | header_len += 8*key_indicator_length; /* add key indicator length */ |
421 | 0 | header_len += au_index_length; /* add AU index length */ |
422 | 0 | first_au_flag = true; |
423 | 0 | } |
424 | 0 | else { /* not the first AU */ |
425 | 0 | if (key_indicator_per_au_flag == true) |
426 | 0 | header_len += 8*key_indicator_length; /* add key indicator length */ |
427 | 0 | header_len += 8*(delta_iv_length); /* add delta IV length */ |
428 | 0 | header_len += au_index_delta_length; /* add AU delta index length */ |
429 | 0 | } |
430 | | /* CTS flag is present? */ |
431 | 0 | if (cts_delta_length != 0) { /* need to test whether cts_delta_flag is true or false */ |
432 | 0 | cts_flag = tvb_get_bits8(tvb, AU_HEADERS_LENGTH_SIZE*8 + header_len, 1); /*fetch 1 bit CTS flag */ |
433 | 0 | header_len += 1; /* add CTS flag bit */ |
434 | 0 | if (cts_flag == 1) |
435 | 0 | header_len += cts_delta_length; /* add CTS delta length bits if CTS flag SET */ |
436 | 0 | } |
437 | | /* DTS flag is present? */ |
438 | 0 | if (dts_delta_length != 0) { /* need to test whether dts_delta_flag is true or false */ |
439 | 0 | dts_flag = tvb_get_bits8(tvb, AU_HEADERS_LENGTH_SIZE*8 + header_len, 1); /*fetch 1 bit DTS flag */ |
440 | 0 | header_len += 1; /* add DTS flag bit */ |
441 | 0 | if (dts_flag == 1) |
442 | 0 | header_len += dts_delta_length; /* add DTS delta length bits if DTS flag SET */ |
443 | 0 | } |
444 | | /* RAP flag present? */ |
445 | 0 | if (random_access_indication != false) |
446 | 0 | header_len += 1; /* add 1 bit RAP flag */ |
447 | | |
448 | | /* stream state indication present */ |
449 | 0 | if (stream_state_indication !=0) |
450 | 0 | header_len += stream_state_indication; /* add stream state indication bits */ |
451 | | |
452 | | /* convert header_len to bytes (rounded up) */ |
453 | 0 | if (header_len% 8 != 0) |
454 | 0 | { |
455 | 0 | header_len_bytes = ((header_len)/8) + 1; /*add 1 */ |
456 | 0 | } |
457 | 0 | else |
458 | 0 | header_len_bytes = ((header_len)/8); |
459 | | |
460 | | /* add AU header tree */ |
461 | 0 | ismacryp_item = proto_tree_add_item(ismacryp_tree, hf_ismacryp_header, tvb, poffset->offset_bytes, header_len_bytes, ENC_NA ); |
462 | 0 | proto_item_append_text(ismacryp_item, ": Length=%d bits", header_len); /* add text to Header tree indicating length */ |
463 | | /* sanity check if actual AU header length is zero bits, which indicates an error */ |
464 | 0 | if ( header_len == 0) /* something wrong */ |
465 | 0 | { |
466 | 0 | proto_item_append_text(ismacryp_item, " Error - zero bit AU header size - check parameters!"); |
467 | 0 | } |
468 | 0 | ismacryp_header_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_header); |
469 | | |
470 | | /* ismacryp header analysis */ |
471 | | |
472 | | /* Extra 1 Byte Header? */ |
473 | |
|
474 | 0 | if ((set_version == V20 && (selective_encryption || slice_indication || padding_indication)) |
475 | 0 | || (set_version == V11 && selective_encryption)) { |
476 | | |
477 | | /* add header byte tree */ |
478 | 0 | ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_header_byte, |
479 | 0 | tvb, poffset->offset_bytes, 1, ENC_NA ); |
480 | 0 | proto_item_append_text(ismacryp_item, ": Length=8 bits"); /* add text to Header byte tree indicating length */ |
481 | 0 | ismacryp_header_byte_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_header_byte); |
482 | | |
483 | | /*ismacryp_header_byte_tree */ |
484 | | /* tvb is network order, so get MSB bits first, so shift 8 bits and work "backwards" */ |
485 | 0 | add_bits(poffset, 7); /*shift 7 bits to get correct bit */ |
486 | | /* AU_is_encrypted bit */ |
487 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
488 | 0 | if (selective_encryption) { /* bit used */ |
489 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_au_is_encrypted, |
490 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit AU_is_encrypted */ |
491 | 0 | } |
492 | 0 | else { /* bit unused */ |
493 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits, |
494 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */ |
495 | 0 | } |
496 | 0 | switch (set_version) { /* ISMACryp version? */ |
497 | 0 | case V11: |
498 | | /* Reserved bits */ |
499 | 0 | add_bits(poffset, -7); /* move back 7 bits for reserved bits */ |
500 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
501 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits, |
502 | 0 | tvb, bit_offset, 7, ENC_BIG_ENDIAN); /*fetch 7 bits reserved */ |
503 | 0 | add_bits(poffset, 8); /* offset to next byte */ |
504 | 0 | break; |
505 | 0 | case V20: |
506 | | /* Slice_start bit */ |
507 | 0 | add_bits(poffset, -1); /* move back 1 bit for slice_start */ |
508 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
509 | 0 | if (slice_indication) { |
510 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_start, |
511 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit slice_start */ |
512 | 0 | } |
513 | 0 | else { /* bit unused */ |
514 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits, |
515 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */ |
516 | 0 | } |
517 | 0 | add_bits(poffset, -1); /* move back 1 bit for slice_end */ |
518 | | |
519 | | /* Slice_end bit */ |
520 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
521 | 0 | if (slice_indication) { |
522 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_end, |
523 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit Slice_end */ |
524 | 0 | } |
525 | 0 | else { /* bit unused */ |
526 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits, |
527 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */ |
528 | 0 | } |
529 | 0 | add_bits(poffset, -3); /* move back 3 bits for padding_bitcount */ |
530 | | |
531 | | /* Padding_bitcount bits */ |
532 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
533 | 0 | if (padding_indication) { |
534 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_padding_bitcount, |
535 | 0 | tvb, bit_offset, 3, ENC_BIG_ENDIAN); /*fetch 3 bits padding_bitcount */ |
536 | 0 | } |
537 | 0 | else { /* bits unused */ |
538 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits, |
539 | 0 | tvb, bit_offset, 3, ENC_BIG_ENDIAN); /*fetch 3 bits unused */ |
540 | 0 | } |
541 | 0 | add_bits(poffset, -2); /* move back 2 bits for reserved bits */ |
542 | | |
543 | | /* Reserved bits */ |
544 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
545 | 0 | proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits, |
546 | 0 | tvb, bit_offset, 2, ENC_BIG_ENDIAN); /*fetch 2 bits reserved */ |
547 | 0 | add_bits(poffset, 8); /* offset to next byte */ |
548 | 0 | break; |
549 | 0 | default: |
550 | 0 | DISSECTOR_ASSERT_NOT_REACHED(); |
551 | 0 | break; |
552 | 0 | } /* end switch set_version */ |
553 | 0 | } /* end selective encryption */ |
554 | | /* IV */ |
555 | 0 | if (first_au_flag == true && iv_length != 0) |
556 | 0 | { |
557 | 0 | ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_iv, tvb, poffset->offset_bytes, iv_length, ENC_NA); |
558 | 0 | proto_item_append_text(ismacryp_item, ": Length=%d bytes", iv_length); /* add IV info */ |
559 | 0 | col_append_fstr( pinfo->cinfo, COL_INFO, |
560 | 0 | ", IV=0x%s", tvb_bytes_to_str_punct(pinfo->pool, tvb, poffset->offset_bytes, iv_length, ' ')); |
561 | |
|
562 | 0 | poffset->offset_bytes += iv_length; /* add IV length to offset_bytes */ |
563 | 0 | } |
564 | | /*Delta IV */ |
565 | 0 | if (first_au_flag == false && delta_iv_length != 0) |
566 | 0 | { |
567 | 0 | ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_delta_iv, |
568 | 0 | tvb, poffset->offset_bytes, delta_iv_length, ENC_NA); |
569 | 0 | proto_item_append_text(ismacryp_item, ": Length=%d bytes", delta_iv_length); /* add delta IV info */ |
570 | 0 | col_append_fstr( pinfo->cinfo, COL_INFO, |
571 | 0 | ", Delta IV=0x%s", tvb_bytes_to_str_punct(pinfo->pool, tvb, poffset->offset_bytes, delta_iv_length, ' ')); |
572 | 0 | poffset->offset_bytes += delta_iv_length; /* add IV length to offset_bytes */ |
573 | 0 | } |
574 | | /* Key Indicator */ |
575 | 0 | if ( key_indicator_length != 0 && ( first_au_flag == true || key_indicator_per_au_flag == true) ) |
576 | 0 | { |
577 | | /* (first AU or KI for each AU) and non-zero KeyIndicator size */ |
578 | 0 | ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_key_indicator, |
579 | 0 | tvb, poffset->offset_bytes, key_indicator_length, ENC_NA); |
580 | 0 | proto_item_append_text(ismacryp_item, ": Length=%d bytes", key_indicator_length); /* add KI info */ |
581 | 0 | col_append_fstr( pinfo->cinfo, COL_INFO, |
582 | 0 | ", KI=0x%s", tvb_bytes_to_str_punct(pinfo->pool, tvb, poffset->offset_bytes, key_indicator_length, ' ')); |
583 | 0 | poffset->offset_bytes += key_indicator_length; /* add KI length to offset_bytes */ |
584 | 0 | } |
585 | | /* AU size */ |
586 | 0 | if (au_size_length != 0) /* in bits */ |
587 | 0 | { |
588 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
589 | 0 | ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_au_size, |
590 | 0 | tvb, bit_offset, au_size_length, ENC_BIG_ENDIAN); |
591 | 0 | proto_item_append_text(ismacryp_item, " bytes: Length=%d bits", au_size_length); /* add AU size info */ |
592 | | /*bit_offset += au_size_length;*/ |
593 | 0 | add_bits(poffset, au_size_length); |
594 | 0 | } |
595 | | /* AU Index */ |
596 | 0 | if (first_au_flag == true && au_index_length != 0) /* first AU and non-zero AU size */ |
597 | 0 | { |
598 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
599 | 0 | ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_au_index, |
600 | 0 | tvb, bit_offset, au_index_length, ENC_BIG_ENDIAN); |
601 | 0 | proto_item_append_text(ismacryp_item, " bits: Length=%d bits", au_index_length); /* add AU index info */ |
602 | | /*bit_offset += au_index_length;*/ |
603 | 0 | add_bits(poffset, au_index_length); |
604 | 0 | } |
605 | | /* AU index delta */ |
606 | 0 | if (first_au_flag == false && au_index_delta_length != 0) /* not first AU and non-zero AU delta size */ |
607 | 0 | { |
608 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
609 | 0 | ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_au_index_delta, |
610 | 0 | tvb, bit_offset, au_index_delta_length, ENC_BIG_ENDIAN); |
611 | 0 | proto_item_append_text(ismacryp_item, ": Length=%d bits", au_index_delta_length); /* add AU index info */ |
612 | | /*bit_offset += au_index_delta_length;*/ |
613 | 0 | add_bits(poffset, au_index_delta_length); |
614 | 0 | } |
615 | | /* CTS delta value */ |
616 | 0 | if (cts_delta_length != 0) |
617 | 0 | { |
618 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
619 | 0 | proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_flag, |
620 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read CTS flag */ |
621 | 0 | add_bits(poffset, 1); |
622 | 0 | if (cts_flag == 1) |
623 | 0 | { |
624 | | /* now fetch CTS delta value (remember offset 1 bit due to CTS flag) */ |
625 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
626 | 0 | ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_delta, |
627 | 0 | tvb, bit_offset, cts_delta_length, ENC_BIG_ENDIAN); /* read CTS delta value */ |
628 | 0 | proto_item_append_text(ismacryp_item, ": Length=%d bits", cts_delta_length); /* add CTS delta info */ |
629 | 0 | add_bits(poffset, cts_delta_length); |
630 | 0 | } |
631 | 0 | } |
632 | | /* DTS delta value */ |
633 | 0 | if (dts_delta_length != 0) |
634 | 0 | { |
635 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
636 | 0 | proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_flag, |
637 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read DTS flag */ |
638 | 0 | add_bits(poffset, 1); |
639 | | |
640 | | /* now fetch DTS delta value (remember offset x bits due to DTS flag) */ |
641 | 0 | if (dts_flag ==1) |
642 | 0 | { |
643 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
644 | 0 | ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_delta, |
645 | 0 | tvb, bit_offset, dts_delta_length, ENC_BIG_ENDIAN); /* read DTS delta value */ |
646 | 0 | proto_item_append_text(ismacryp_item, ": Length=%d bits", dts_delta_length); /* add DTS delta info */ |
647 | 0 | add_bits(poffset, dts_delta_length); |
648 | 0 | } |
649 | 0 | } |
650 | | /* RAP */ |
651 | 0 | if (random_access_indication != false) |
652 | 0 | { |
653 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
654 | 0 | proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_rap_flag, |
655 | 0 | tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read RAP flag */ |
656 | 0 | add_bits(poffset, 1); |
657 | 0 | } |
658 | | /*STREAM STATE */ |
659 | 0 | if (stream_state_indication != 0) |
660 | 0 | { |
661 | 0 | bit_offset = (poffset->offset_bytes)*8 + poffset->offset_bits; /* offset in bits */ |
662 | 0 | proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_stream_state, |
663 | 0 | tvb, bit_offset, stream_state_indication, ENC_BIG_ENDIAN); /* read stream state */ |
664 | 0 | add_bits(poffset, stream_state_indication); |
665 | 0 | } |
666 | 0 | return poffset; |
667 | 0 | } |
668 | | |
669 | | /* add len_bits to offset bits and bytes, handling bits overflow */ |
670 | | static void add_bits(offset_struct* poffset, int len_bits) |
671 | 0 | { |
672 | 0 | int nbbitstotal; |
673 | 0 | nbbitstotal = poffset->offset_bytes*8 + (poffset->offset_bits) + len_bits; /* total offset in bits */ |
674 | | /* now calculate bytes and bit offsets */ |
675 | 0 | poffset->offset_bytes = (nbbitstotal / 8); /* add integer no. of bytes */ |
676 | 0 | poffset->offset_bits = (nbbitstotal % 8); /* add remaining bits */ |
677 | 0 | } |
678 | | |
679 | | void proto_register_ismacryp (void) |
680 | 14 | { |
681 | | /* A header field is something you can search/filter on. |
682 | | * |
683 | | * We create a structure to register our fields. It consists of an |
684 | | * array of hf_register_info structures, each of which are of the format |
685 | | * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}. |
686 | | */ |
687 | 14 | static hf_register_info hf[] = { |
688 | | #if 0 |
689 | | { &hf_ismacryp, |
690 | | { "Data", "ismacryp.data", FT_NONE, BASE_NONE, NULL, 0x0, |
691 | | NULL, HFILL }}, |
692 | | #endif |
693 | | |
694 | | #if 0 |
695 | | { &hf_ismacryp_length, |
696 | | { "Total Length", "ismacryp.len", FT_UINT16, BASE_DEC, NULL, 0x0, /* length 2 bytes, print as decimal value */ |
697 | | NULL, HFILL }}, |
698 | | #endif |
699 | | |
700 | 14 | { &hf_ismacryp_header, |
701 | 14 | { "AU Header", "ismacryp.header", FT_NONE, BASE_NONE, NULL, 0x0, |
702 | 14 | NULL, HFILL }}, |
703 | | |
704 | | #if 0 |
705 | | { &hf_ismacryp_header_length, |
706 | | { "Header Length", "ismacryp.header.length", FT_UINT16, BASE_DEC, NULL, 0x0, |
707 | | NULL, HFILL }}, |
708 | | #endif |
709 | | |
710 | 14 | { &hf_ismacryp_au_headers_length, |
711 | 14 | { "AU Headers Length", "ismacryp.au_headers.length", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_bits), 0x0, |
712 | 14 | NULL, HFILL }}, |
713 | | |
714 | 14 | { &hf_ismacryp_header_byte, |
715 | 14 | { "Header Byte", "ismacryp.header.byte", FT_NONE, BASE_NONE, NULL, 0x0, /* 1 byte */ |
716 | 14 | NULL, HFILL }}, |
717 | | |
718 | | #if 0 |
719 | | { &hf_ismacryp_version, |
720 | | { "Version", "ismacryp.version", FT_UINT8, BASE_HEX, NULL, 0x0, /* version 1 byte */ |
721 | | NULL, HFILL }}, |
722 | | #endif |
723 | | |
724 | 14 | { &hf_ismacryp_message, |
725 | 14 | { "Message", "ismacryp.message", FT_NONE, BASE_NONE, NULL, 0x0, |
726 | 14 | NULL, HFILL }}, |
727 | | |
728 | | #if 0 |
729 | | { &hf_ismacryp_message_length, |
730 | | { "Message Length", "ismacryp.message.len", FT_UINT16, BASE_DEC, NULL, 0x0, /* length 2 bytes, print as decimal value */ |
731 | | NULL, HFILL }}, |
732 | | #endif |
733 | | |
734 | | #if 0 |
735 | | { &hf_ismacryp_parameter, |
736 | | { "Parameter", "ismacryp.parameter", FT_NONE, BASE_NONE, NULL, 0x0, |
737 | | NULL, HFILL }}, |
738 | | #endif |
739 | | |
740 | | #if 0 |
741 | | { &hf_ismacryp_parameter_length, |
742 | | { "Parameter Length", "ismacryp.parameter.len", FT_UINT16, BASE_DEC, NULL, 0x0, /* length 2 bytes, print as decimal value */ |
743 | | NULL, HFILL }}, |
744 | | #endif |
745 | | |
746 | 14 | { &hf_ismacryp_iv, |
747 | 14 | { "IV", "ismacryp.iv", FT_BYTES, BASE_NONE, NULL, 0x0, /* variable length */ |
748 | 14 | NULL, HFILL }}, |
749 | | |
750 | 14 | { &hf_ismacryp_delta_iv, |
751 | 14 | { "Delta IV", "ismacryp.delta_iv", FT_BYTES, BASE_NONE, NULL, 0x0, /* variable length */ |
752 | 14 | NULL, HFILL }}, |
753 | | |
754 | 14 | { &hf_ismacryp_key_indicator, |
755 | 14 | { "Key Indicator", "ismacryp.key_indicator", FT_BYTES, BASE_NONE, NULL, 0x0, /* variable length */ |
756 | 14 | NULL, HFILL }}, |
757 | | |
758 | | #if 0 |
759 | | { &hf_ismacryp_parameter_value, |
760 | | { "Parameter Value", "ismacryp.parameter.value", FT_NONE, BASE_NONE, NULL, 0x0, |
761 | | NULL, HFILL }}, |
762 | | #endif |
763 | | |
764 | 14 | { &hf_ismacryp_au_size, |
765 | 14 | { "AU size", "ismacryp.au.size", FT_UINT64, BASE_DEC, NULL, 0x0, |
766 | 14 | NULL, HFILL }}, |
767 | | |
768 | 14 | { &hf_ismacryp_au_index, |
769 | 14 | { "AU index", "ismacryp.au.index", FT_UINT64, BASE_DEC, NULL, 0x0, |
770 | 14 | NULL, HFILL }}, |
771 | | |
772 | 14 | { &hf_ismacryp_au_index_delta, |
773 | 14 | { "AU index delta", "ismacryp.au.index_delta", FT_UINT64, BASE_DEC, NULL, 0x0, |
774 | 14 | NULL, HFILL }}, |
775 | | |
776 | 14 | { &hf_ismacryp_cts_delta, |
777 | 14 | { "CTS delta", "ismacryp.cts_delta", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
778 | 14 | NULL, HFILL }}, |
779 | | |
780 | 14 | { &hf_ismacryp_cts_flag, |
781 | 14 | { "CTS flag", "ismacryp.cts_flag", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
782 | 14 | NULL, HFILL }}, |
783 | | |
784 | 14 | { &hf_ismacryp_dts_delta, |
785 | 14 | { "DTS delta", "ismacryp.dts_delta", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
786 | 14 | NULL, HFILL }}, |
787 | | |
788 | 14 | { &hf_ismacryp_dts_flag, |
789 | 14 | { "DTS flag", "ismacryp.dts_flag", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
790 | 14 | NULL, HFILL }}, |
791 | | |
792 | 14 | { &hf_ismacryp_rap_flag, |
793 | 14 | { "RAP flag", "ismacryp.rap_flag", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
794 | 14 | NULL, HFILL }}, |
795 | | |
796 | 14 | { &hf_ismacryp_stream_state, |
797 | 14 | { "Stream state", "ismacryp.stream_state", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
798 | 14 | NULL, HFILL }}, |
799 | | |
800 | 14 | { &hf_ismacryp_au_is_encrypted, |
801 | 14 | { "AU_is_encrypted flag", "ismacryp.au_is_encrypted", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
802 | 14 | NULL, HFILL }}, |
803 | | |
804 | 14 | { &hf_ismacryp_slice_start, |
805 | 14 | { "Slice_start flag", "ismacryp.slice_start", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
806 | 14 | NULL, HFILL }}, |
807 | | |
808 | 14 | { &hf_ismacryp_slice_end, |
809 | 14 | { "Slice_end flag", "ismacryp.slice_end", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
810 | 14 | NULL, HFILL }}, |
811 | | |
812 | 14 | { &hf_ismacryp_padding_bitcount, |
813 | 14 | { "Padding_bitcount bits", "ismacryp.padding_bitcount", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
814 | 14 | NULL, HFILL }}, |
815 | | |
816 | 14 | { &hf_ismacryp_padding, |
817 | 14 | { "Padding bits", "ismacryp.padding", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
818 | 14 | NULL, HFILL }}, |
819 | | |
820 | 14 | { &hf_ismacryp_reserved_bits, |
821 | 14 | { "Reserved bits", "ismacryp.reserved", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
822 | 14 | NULL, HFILL }}, |
823 | | |
824 | 14 | { &hf_ismacryp_unused_bits, |
825 | 14 | { "Unused bits", "ismacryp.unused", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
826 | 14 | NULL, HFILL }} |
827 | 14 | }; |
828 | | |
829 | 14 | static int *ett[] = |
830 | 14 | { |
831 | 14 | &ett_ismacryp, |
832 | 14 | &ett_ismacryp_header, |
833 | 14 | &ett_ismacryp_header_byte, |
834 | 14 | &ett_ismacryp_message |
835 | 14 | }; |
836 | | |
837 | 14 | static const enum_val_t version_types[] = { |
838 | 14 | {PROTO_TAG_ISMACRYP_11, "ISMACryp v1.1", V11}, |
839 | 14 | {PROTO_TAG_ISMACRYP_20, "ISMACryp v2.0", V20}, |
840 | 14 | {NULL, NULL, -1} |
841 | 14 | }; |
842 | | |
843 | 14 | static const enum_val_t mode_types[] = { |
844 | 14 | {"aac-hbr", "aac-hbr", AAC_HBR_MODE}, |
845 | 14 | {"mpeg4-video", "mpeg4-video", MPEG4_VIDEO_MODE}, |
846 | 14 | {"avc-video", "avc-video", AVC_VIDEO_MODE}, |
847 | 14 | {NULL, NULL, -1} |
848 | 14 | }; |
849 | | |
850 | 14 | module_t *ismacryp_module; |
851 | | |
852 | 14 | proto_ismacryp = proto_register_protocol ("ISMACryp Protocol", "ISMACRYP", "ismacryp"); |
853 | 14 | proto_ismacryp_v11 = proto_register_protocol_in_name_only ("ISMACryp Protocol v1.1", |
854 | 14 | "ISMACRYP 1.1", "ismacryp_v11", proto_ismacryp, FT_PROTOCOL); |
855 | 14 | proto_ismacryp_v20 = proto_register_protocol_in_name_only ("ISMACryp Protocol v2.0", |
856 | 14 | "ISMACRYP 2.0", "ismacryp_v20", proto_ismacryp, FT_PROTOCOL); |
857 | 14 | proto_register_field_array (proto_ismacryp, hf, array_length (hf)); |
858 | 14 | proto_register_subtree_array (ett, array_length (ett)); |
859 | | |
860 | 14 | ismacryp_handle = register_dissector("ismacryp", dissect_ismacryp, proto_ismacryp); |
861 | 14 | ismacryp_v11_handle = register_dissector("ismacryp_v11", dissect_ismacryp_v11, proto_ismacryp_v11); |
862 | 14 | ismacryp_v20_handle = register_dissector("ismacryp_v20", dissect_ismacryp_v20, proto_ismacryp_v20); |
863 | | |
864 | | /* Register our configuration options for ismacryp */ |
865 | 14 | ismacryp_module = prefs_register_protocol(proto_ismacryp, NULL); |
866 | | |
867 | 14 | prefs_register_obsolete_preference(ismacryp_module, "dynamic.payload.type"); |
868 | | |
869 | 14 | prefs_register_enum_preference(ismacryp_module, "version", |
870 | 14 | "ISMACryp version", |
871 | 14 | "ISMACryp version", |
872 | 14 | &version_type, version_types, true); |
873 | | |
874 | 14 | prefs_register_static_text_preference(ismacryp_module, "text_override", |
875 | 14 | "The following option allows the version to be set manually" |
876 | 14 | " and to override the version if detected from RTP payload type:", |
877 | 14 | "The following option allows the version to be set manually" |
878 | 14 | " and to override the version if detected from RTP payload type:"); |
879 | | |
880 | 14 | prefs_register_bool_preference(ismacryp_module, |
881 | 14 | "override_rtp_pt", "Override RTP payload type for version", |
882 | 14 | "Indicates whether or not the ISMACryp version deduced" |
883 | 14 | " from RTP payload type, if present, is used or whether the" |
884 | 14 | " version above is used", |
885 | 14 | &override_flag); |
886 | | |
887 | | /* ISMACryp v11 parameters */ |
888 | 14 | prefs_register_static_text_preference(ismacryp_module, |
889 | 14 | "v11_parameters", |
890 | 14 | "ISMACryp v1.1 parameters:", |
891 | 14 | "ISMACryp v1.1 parameters declared in SDP"); |
892 | | |
893 | 14 | prefs_register_uint_preference(ismacryp_module, |
894 | 14 | "iv_length", "ISMACrypIVLength (bytes)", |
895 | 14 | "Set the length of the IV in the ISMACryp AU Header in bytes", |
896 | 14 | 10, &iv_length); |
897 | | |
898 | 14 | prefs_register_uint_preference(ismacryp_module, |
899 | 14 | "delta_iv_length", "ISMACrypDeltaIVLength (bytes)", |
900 | 14 | "Set the length of the Delta IV in the ISMACryp AU Header in bytes", |
901 | 14 | 10, &delta_iv_length); |
902 | | |
903 | 14 | prefs_register_uint_preference(ismacryp_module, |
904 | 14 | "key_indicator_length", "ISMACrypKeyIndicatorLength (bytes)", |
905 | 14 | "Set the length of the Key Indicator in the ISMACryp AU Header in bytes", |
906 | 14 | 10, &key_indicator_length); |
907 | | |
908 | 14 | prefs_register_bool_preference(ismacryp_module, |
909 | 14 | "key_indicator_per_au_flag", "ISMACrypKeyIndicatorPerAU (T/F)", |
910 | 14 | "Indicates whether or not the Key Indicator is present in all AU Headers (T/F)", |
911 | 14 | &key_indicator_per_au_flag); |
912 | | |
913 | 14 | prefs_register_bool_preference(ismacryp_module, |
914 | 14 | "selective_encryption", "ISMACrypSelectiveEncryption (T/F)", |
915 | 14 | "Indicates whether or not selective encryption is enabled (T/F)", |
916 | 14 | &selective_encryption); |
917 | | |
918 | | /* ISMACryp v20 parameters */ |
919 | 14 | prefs_register_static_text_preference(ismacryp_module, |
920 | 14 | "v20_parameters", |
921 | 14 | "ISMACryp v2.0 parameters:", |
922 | 14 | "ISMACryp v2.0 parameters declared in SDP"); |
923 | | |
924 | 14 | prefs_register_bool_preference(ismacryp_module, |
925 | 14 | "slice_indication", "ISMACrypSliceIndication (T/F)", |
926 | 14 | "Indicates whether or not slice start / end is present (T/F)", |
927 | 14 | &slice_indication); |
928 | | |
929 | 14 | prefs_register_bool_preference(ismacryp_module, |
930 | 14 | "padding_indication", "ISMACrypPaddingIndication (T/F)", |
931 | 14 | "Indicates whether or not padding information is present (T/F)", |
932 | 14 | &padding_indication); |
933 | | |
934 | | /* RFC3640 mode - ISMACryp v11 */ |
935 | 14 | prefs_register_static_text_preference(ismacryp_module, |
936 | 14 | "codec_modes", |
937 | 14 | "Codec mode selection (RFC3640 for ISMACryp v1.1 only):", |
938 | 14 | "AU parameters set according to RFC3640 mode or user defined"); |
939 | | |
940 | 14 | prefs_register_enum_preference(ismacryp_module, |
941 | 14 | "rfc3640_mode", |
942 | 14 | "RFC3640 mode", |
943 | 14 | "RFC3640 mode", |
944 | 14 | &mode, mode_types, true); |
945 | | |
946 | | /* User defined mode */ |
947 | 14 | prefs_register_bool_preference(ismacryp_module, |
948 | 14 | "user_mode", "User mode (T/F)", |
949 | 14 | "Indicates use of user mode instead of RFC3640 modes (T/F)", |
950 | 14 | &pref_user_mode); |
951 | | |
952 | | /* following preference values only used if user mode is selected above */ |
953 | 14 | prefs_register_static_text_preference(ismacryp_module, |
954 | 14 | "user_defined_modes", |
955 | 14 | "Following parameters only valid and used for user mode:", |
956 | 14 | "AU parameters defined by the user"); |
957 | | |
958 | | /* ideally would grey this out or disable this if in user mode */ |
959 | 14 | prefs_register_uint_preference(ismacryp_module, |
960 | 14 | "au_size_length", "User mode: SizeLength (bits)", |
961 | 14 | "Set the length of the AU size in the AU Header in bits", |
962 | 14 | 10, &pref_au_size_length); |
963 | | |
964 | 14 | prefs_register_uint_preference(ismacryp_module, |
965 | 14 | "au_index_length", "User mode: IndexLength (bits)", |
966 | 14 | "Set the length of the AU index in the AU Header in bits", |
967 | 14 | 10, &pref_au_index_length); |
968 | | |
969 | 14 | prefs_register_uint_preference(ismacryp_module, |
970 | 14 | "au_index_delta_length", "User mode: IndexDeltaLength (bits)", |
971 | 14 | "Set the length of the AU delta index in the AU Header in bits", |
972 | 14 | 10, &pref_au_index_delta_length); |
973 | | |
974 | 14 | prefs_register_uint_preference(ismacryp_module, |
975 | 14 | "cts_delta_length", "User mode: CTSDeltaLength (bits)", |
976 | 14 | "Set the length of the CTS delta field in the AU Header in bits", |
977 | 14 | 10, &pref_cts_delta_length); |
978 | | |
979 | 14 | prefs_register_uint_preference(ismacryp_module, |
980 | 14 | "dts_delta_length", "User mode: DTSDeltaLength (bits)", |
981 | 14 | "Set the length of the DTS delta field in the AU Header in bits", |
982 | 14 | 10, &pref_dts_delta_length); |
983 | | |
984 | 14 | prefs_register_bool_preference(ismacryp_module, |
985 | 14 | "random_access_indication", "User mode: RandomAccessIndication (T/F)", |
986 | 14 | "Indicates whether or not the RAP field is present in the AU Header (T/F)", |
987 | 14 | &pref_random_access_indication); |
988 | | |
989 | 14 | prefs_register_uint_preference(ismacryp_module, |
990 | 14 | "stream_state_indication", "User mode: StreamStateIndication (number of bits)", |
991 | 14 | "Indicates the number of bits on which the stream state field is encoded" |
992 | 14 | " in the AU Header (bits)", |
993 | 14 | 10, &pref_stream_state_indication); |
994 | 14 | } |
995 | | |
996 | | void proto_reg_handoff_ismacryp(void) |
997 | 14 | { |
998 | 14 | dissector_add_string("rtp_dyn_payload_type", "ISMACRYP", ismacryp_handle); |
999 | 14 | dissector_add_string("rtp_dyn_payload_type", "enc-mpeg4-generic", ismacryp_v11_handle); |
1000 | 14 | dissector_add_string("rtp_dyn_payload_type", "enc-isoff-generic", ismacryp_v20_handle); |
1001 | 14 | dissector_add_uint_range_with_preference("rtp.pt", "", ismacryp_handle); |
1002 | | |
1003 | 14 | } |
1004 | | |
1005 | | /* |
1006 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1007 | | * |
1008 | | * Local variables: |
1009 | | * c-basic-offset: 8 |
1010 | | * tab-width: 8 |
1011 | | * indent-tabs-mode: t |
1012 | | * End: |
1013 | | * |
1014 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
1015 | | * :indentSize=8:tabSize=8:noTabs=false: |
1016 | | */ |