69917fa1ed354fc91f9657973b67cb65330ccfe5
[obnox/wireshark/wip.git] / plugins / docsis / packet-mdd.c
1 /* packet-mdd.c
2  * $Id$
3  * Routines for MDD Message dissection
4  * Copyright 2007, Bruno Verstuyft  <bruno.verstuyft@excentis.com>
5  *
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
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.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <epan/packet.h>
31
32
33 #define DOWNSTREAM_ACTIVE_CHANNEL_LIST 1
34 #define MAC_DOMAIN_DOWNSTREAM_SERVICE_GROUP 2
35 #define DOWNSTREAM_AMBIGUITY_RESOLUTION_FREQUENCY_LIST 3
36 #define RECEIVE_CHANNEL_PROFILE_REPORTING_CONTROL 4
37 #define IP_INITIALIZATION_PARAMETERS 5
38 #define EARLY_AUTHENTICATION_AND_ENCRYPTION 6
39 #define UPSTREAM_ACTIVE_CHANNEL_LIST 7
40 #define UPSTREAM_AMBIGUITY_RESOLUTION_CHANNEL_LIST 8
41 #define UPSTREAM_FREQUENCY_RANGE 9
42 #define SYMBOL_CLOCK_LOCKING_INDICATOR 10
43 #define CM_STATUS_EVENT_CONTROL 11
44 #define UPSTREAM_TRANSMIT_POWER_REPORTING 12
45 #define DSG_DA_TO_DSID_ASSOCIATION_ENTRY 13
46 #define CM_STATUS_EVENT_ENABLE_NON_CHANNEL_SPECIFIC_EVENTS 15
47
48 /*Downstream Active Channel List*/
49 #define DOWNSTREAM_ACTIVE_CHANNEL_LIST_CHANNEL_ID 1
50 #define DOWNSTREAM_ACTIVE_CHANNEL_LIST_FREQUENCY 2
51 #define DOWNSTREAM_ACTIVE_CHANNEL_LIST_MODULATION_ORDER_ANNEX 3
52 #define DOWNSTREAM_ACTIVE_CHANNEL_LIST_PRIMARY_CAPABLE 4
53 #define DOWNSTREAM_ACTIVE_CHANNEL_LIST_CM_STATUS_EVENT_ENABLE_BITMASK 5
54
55 /*Mac Domain Downstream Service Group*/
56 #define MAC_DOMAIN_DOWNSTREAM_SERVICE_GROUP_MD_DS_SG_IDENTIFIER 1
57 #define MAC_DOMAIN_DOWNSTREAM_SERVICE_GROUP_CHANNEL_IDS 2
58
59 /*Modulation Orders*/
60 #define QAM64 0
61 #define QAM256 1
62
63 /*Annexes*/
64 #define J83_ANNEX_A 0
65 #define J83_ANNEX_B 1
66 #define J83_ANNEX_C 2
67
68 /*Primary Capable*/
69 #define NOT_PRIMARY_CAPABLE 0
70 #define PRIMARY_CAPABLE 1
71
72 /*Receive Channel Profile Reporting Control*/
73 #define RCP_CENTER_FREQUENCY_SPACING 1
74 #define VERBOSE_RCP_REPORTING 2
75
76 /*Frequency spacing*/
77 #define ASSUME_6MHZ_CENTER_FREQUENCY_SPACING 0
78 #define ASSUME_8MHZ_CENTER_FREQUENCY_SPACING 1
79
80 /*Verbose RCP reporting*/
81 #define RCP_NO_VERBOSE_REPORTING 0
82 #define RCP_VERBOSE_REPORTING 1
83
84 /*Sub-TLVs for IP Initialization Parameters*/
85 #define IP_PROVISIONING_MODE 1
86 #define PRE_REGISTRATION_DSID 2
87
88 /*IP Provisioning Modes*/
89 #define IPv4_ONLY 0
90 #define IPv6_ONLY 1
91 #define IP_ALTERNATE 2
92 #define DUAL_STACK 3
93
94 /*Early authentication and encryption*/
95 #define EAE_DISABLED 0
96 #define EAE_ENABLED 1
97
98 /*Upstream Active Channel List*/
99 #define UPSTREAM_ACTIVE_CHANNEL_LIST_UPSTREAM_CHANNEL_ID 1
100 #define UPSTREAM_ACTIVE_CHANNEL_LIST_CM_STATUS_EVENT_ENABLE_BITMASK 2
101
102 /*Upstream Frequency Range*/
103 #define STANDARD_UPSTREAM_FREQUENCY_RANGE 0
104 #define EXTENDED_UPSTREAM_FREQUENCY_RANGE 1
105
106 /*Symbol Clock Locking Indicator*/
107 #define NOT_LOCKED_TO_MASTER_CLOCK 0
108 #define LOCKED_TO_MASTER_CLOCK 1
109
110 /*CM-STATUS Event Control */
111 #define EVENT_TYPE_CODE 1
112 #define MAXIMUM_EVENT_HOLDOFF_TIMER 2
113 #define MAXIMUM_NUMBER_OF_REPORTS_PER_EVENT 3
114
115 /*CM-STATUS Events*/
116 #define SECONDARY_CHANNEL_MDD_TIMEOUT 1
117 #define QAM_FEC_LOCK_FAILURE 2
118 #define SEQUENCE_OUT_OF_RANGE 3
119 #define MDD_RECOVERY 4
120 #define QAM_FEC_LOCK_RECOVERY 5
121 #define T4_TIMEOUT 6
122 #define T3_RETRIES_EXCEEDED 7
123 #define SUCCESFUL_RANGING_AFTER_T3_RETRIES_EXCEEDED 8
124 #define CM_OPERATING_ON_BATTERY_BACKUP 9
125 #define CM_RETURNED_TO_AC_POWER 10
126
127 /*Upstream Transmit Power Reporting*/
128 #define CM_DOESNT_REPORT_TRANSMIT_POWER 0
129 #define CM_REPORTS_TRANSMIT_POWER 1
130
131
132 /*Dsg DA to DSID association entry*/
133 #define DSG_DA_TO_DSID_ASSOCIATION_DA 1
134 #define DSG_DA_TO_DSID_ASSOCIATION_DSID 2
135
136
137
138
139 static const value_string J83_annex_vals[] = {
140         {J83_ANNEX_A, "J.83 Annex A"},
141         {J83_ANNEX_B, "J.83 Annex B"},
142         {J83_ANNEX_C, "J.83 Annex C"},
143         {0, NULL}
144 };
145
146
147 static const value_string modulation_order_vals[] = {
148         {QAM64, "64 QAM"},
149         {QAM256, "256 QAM"},
150         {0, NULL}
151 };
152
153 static const value_string primary_capable_vals[] = {
154         {NOT_PRIMARY_CAPABLE, "Channel is not primary-capable"},
155         {PRIMARY_CAPABLE, "channel is primary-capable"},
156         {0, NULL}
157 };
158
159
160 static const value_string mdd_tlv_vals[] = {
161          {DOWNSTREAM_ACTIVE_CHANNEL_LIST, "Downstream Active Channel List"},
162          {MAC_DOMAIN_DOWNSTREAM_SERVICE_GROUP, "Mac Domain Downstream Service Group"},
163          {DOWNSTREAM_AMBIGUITY_RESOLUTION_FREQUENCY_LIST, "Downstream Ambiguity Resolution Frequency List "},
164          {RECEIVE_CHANNEL_PROFILE_REPORTING_CONTROL , "Receive Channel Profile Reporting Control"},
165          {IP_INITIALIZATION_PARAMETERS , "IP Initialization Parameters"},
166          {EARLY_AUTHENTICATION_AND_ENCRYPTION , "Early Authentication and Encryption"},
167          {UPSTREAM_ACTIVE_CHANNEL_LIST , "Upstream Active Channel List"},
168          {UPSTREAM_AMBIGUITY_RESOLUTION_CHANNEL_LIST , "Upstream Ambiguity Resolution Channel List"},
169          {UPSTREAM_FREQUENCY_RANGE  , "Upstream Frequency Range"},
170          {SYMBOL_CLOCK_LOCKING_INDICATOR  , "Symbol Clock Locking Indicator"},
171          {CM_STATUS_EVENT_CONTROL  , "CM-STATUS Event Control"},
172          {UPSTREAM_TRANSMIT_POWER_REPORTING  , "Upstream Transmit Power Reporting"},
173          {DSG_DA_TO_DSID_ASSOCIATION_ENTRY  , "DSG DA-to-DSID Association Entry"},
174          {CM_STATUS_EVENT_ENABLE_NON_CHANNEL_SPECIFIC_EVENTS  , 
175                 "CM-STATUS Event Enable for Non-Channel-Specific-Events"},
176         {0, NULL}
177 };
178
179
180 static const value_string rpc_center_frequency_spacing_vals[] = {
181         {ASSUME_6MHZ_CENTER_FREQUENCY_SPACING  , "CM MUST report only Receive Channel Profiles assuming 6 MHz center frequency spacing"},
182         {ASSUME_8MHZ_CENTER_FREQUENCY_SPACING  , "CM MUST report only Receive Channel Profiles assuming 8 MHz center frequency spacing"},
183         {0, NULL}
184 };
185
186 static const value_string verbose_rpc_reporting_vals[] = {
187         {RCP_NO_VERBOSE_REPORTING  , "CM MUST NOT provide verbose reporting of all its Receive Channel Profile(s) (both standard profiles and manufacturers profiles)."},
188         {RCP_VERBOSE_REPORTING  , "CM MUST provide verbose reporting of Receive Channel Profile(s) (both standard profiles and manufacturers profiles)."},
189         {0, NULL}
190 };
191
192 static const value_string ip_provisioning_mode_vals[] = {
193         {IPv4_ONLY  , "IPv4 Only"},
194         {IPv6_ONLY , "IPv6 Only"},
195         {IP_ALTERNATE, "Alternate"},
196         {DUAL_STACK , "Dual Stack"},
197         {0, NULL}
198 };
199
200 static const value_string eae_vals[] = {
201         {EAE_DISABLED  , "early authentication and encryption disabled"},
202         {EAE_ENABLED , "early authentication and encryption enabled"},
203         {0, NULL}
204 };
205
206 static const value_string upstream_frequency_range_vals[] = {
207         {STANDARD_UPSTREAM_FREQUENCY_RANGE, "Standard Upstream Frequency Range"},
208         {EXTENDED_UPSTREAM_FREQUENCY_RANGE, "Extended Upstream Frequency Range"},
209         {0, NULL}
210 };
211
212 static const value_string symbol_clock_locking_indicator_vals[] = {
213         {NOT_LOCKED_TO_MASTER_CLOCK, "Symbol Clock is not locked to Master Clock"},
214         {LOCKED_TO_MASTER_CLOCK, "Symbol Clock is locked to Master Clock"},
215         {0, NULL}
216 };
217
218 static const value_string symbol_cm_status_event_vals[] = {
219         {SECONDARY_CHANNEL_MDD_TIMEOUT, "Secondary Channel MDD timeout"},
220         {QAM_FEC_LOCK_FAILURE, "Qam FEC Lock Failure"},
221         {SEQUENCE_OUT_OF_RANGE, "Sequence out of Range"},
222         {MDD_RECOVERY, "MDD Recovery"},
223         {QAM_FEC_LOCK_RECOVERY, "Qam FEC Lock Recovery"},
224         {T4_TIMEOUT, "T4 Timeout"},
225         {T3_RETRIES_EXCEEDED, "T3 Retries Exceeded"},
226         {SUCCESFUL_RANGING_AFTER_T3_RETRIES_EXCEEDED, "Successful ranging after T3 Retries Exceeded"},
227         {CM_OPERATING_ON_BATTERY_BACKUP, "CM Operating on Battery Backup"},
228         {CM_RETURNED_TO_AC_POWER, "CM Returned to AC Power"},
229         {0, NULL}
230 };
231
232 static const value_string upstream_transmit_power_reporting_vals[] = {
233         {CM_DOESNT_REPORT_TRANSMIT_POWER, "CM does not report transmit power in RNG-REQ, INIT-RNG-REQ, and B-INIT-RNG-REQ messages"},
234         {CM_REPORTS_TRANSMIT_POWER, "CM reports transmit power in RNG-REQ, INIT-RNG-REQ, and B-INIT-RNG-REQ messages"},
235         {0, NULL}
236 };
237
238
239
240 /* Initialize the protocol and registered fields */
241 static int proto_docsis_mdd = -1;
242 static int hf_docsis_mdd_ccc = -1;
243 static int hf_docsis_mdd_number_of_fragments = -1;
244 static int hf_docsis_mdd_fragment_sequence_number = -1;
245 static int hf_docsis_mdd_current_channel_dcid = -1;
246
247 static int hf_docsis_mdd_downstream_active_channel_list_channel_id = -1;
248 static int hf_docsis_mdd_downstream_active_channel_list_frequency = -1;
249 static int hf_docsis_mdd_downstream_active_channel_list_annex = -1;
250 static int hf_docsis_mdd_downstream_active_channel_list_modulation_order = -1;
251 static int hf_docsis_mdd_downstream_active_channel_list_primary_capable = -1;
252
253 static int hf_docsis_mdd_cm_status_event_enable_bitmask_mdd_timeout = -1;
254 static int hf_docsis_mdd_cm_status_event_enable_bitmask_qam_fec_lock_failure = -1;
255 static int hf_docsis_mdd_cm_status_event_enable_bitmask_mdd_recovery = -1;
256 static int hf_docsis_mdd_cm_status_event_enable_bitmask_qam_fec_lock_recovery = -1;
257 static int hf_docsis_mdd_cm_status_event_enable_bitmask_t4_timeout = -1;
258 static int hf_docsis_mdd_cm_status_event_enable_bitmask_t3_retries_exceeded = -1;
259 static int hf_docsis_mdd_cm_status_event_enable_bitmask_successful_ranging_after_t3_retries_exceeded = -1;
260
261
262 static int hf_docsis_mdd_mac_domain_downstream_service_group_md_ds_sg_identifier = -1;
263 static int hf_docsis_mdd_mac_domain_downstream_service_group_channel_id = -1;
264
265 static int hf_docsis_mdd_downstream_ambiguity_resolution_frequency = -1;
266
267 static int hf_docsis_mdd_rpc_center_frequency_spacing = -1;
268 static int hf_docsis_mdd_verbose_rcp_reporting = -1;
269
270 static int hf_docsis_mdd_ip_provisioning_mode = -1;
271 static int hf_docsis_mdd_pre_registration_dsid = -1;
272
273 static int hf_docsis_mdd_early_authentication_and_encryption = -1;
274
275 static int hf_docsis_mdd_upstream_active_channel_list_upstream_channel_id = -1;
276
277 static int hf_docsis_mdd_upstream_ambiguity_resolution_channel_list_channel_id = -1;
278
279 static int hf_docsis_mdd_upstream_frequency_range = -1;
280
281 static int hf_docsis_mdd_symbol_clock_locking_indicator = -1;
282
283 static int hf_docsis_mdd_event_type = -1;
284
285 static int hf_docsis_mdd_maximum_event_holdoff_timer = -1;
286
287 static int hf_docsis_mdd_maximum_number_of_reports_per_event = -1;
288 static int hf_docsis_mdd_upstream_transmit_power_reporting = -1;
289
290 static int hf_docsis_mdd_dsg_da_to_dsid_association_da = -1;
291 static int hf_docsis_mdd_dsg_da_to_dsid_association_dsid = -1;
292
293 static int hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_sequence_out_of_range = -1;
294 static int hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_cm_operating_on_battery_backup = -1;
295 static int hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_cm_returned_to_ac_power = -1;
296
297
298 /* Initialize the subtree pointers */
299 static gint ett_docsis_mdd = -1;
300 static gint ett_tlv = -1;
301 static gint ett_sub_tlv = -1;
302
303 static void
304 dissect_mdd (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
305 {
306         proto_item *it;
307         proto_tree *mdd_tree;
308
309         int pos;
310         int subpos = 0;
311         gint len;
312         guint8 type, length;
313         guint8 subtype, sublength;
314         int i;
315
316         proto_item *tlv_item;
317         proto_tree *tlv_tree;
318
319         proto_item *tlv_sub_item;
320         proto_tree *tlv_sub_tree;
321         proto_item *text_item;
322
323
324         len = tvb_reported_length_remaining (tvb, 0);
325
326         col_set_str(pinfo->cinfo, COL_INFO, "MDD Message:");
327
328         if (tree)
329         {
330                 it = proto_tree_add_protocol_format (tree, proto_docsis_mdd, tvb, 0, -1,"MDD Message");
331                 mdd_tree = proto_item_add_subtree (it, ett_docsis_mdd);
332
333                 proto_tree_add_item (mdd_tree, hf_docsis_mdd_ccc, tvb, 0, 1, ENC_BIG_ENDIAN);
334                 proto_tree_add_item (mdd_tree, hf_docsis_mdd_number_of_fragments, tvb, 1, 1, ENC_BIG_ENDIAN);
335                 proto_tree_add_item (mdd_tree, hf_docsis_mdd_fragment_sequence_number, tvb, 2, 1, ENC_BIG_ENDIAN);
336                 proto_tree_add_item (mdd_tree, hf_docsis_mdd_current_channel_dcid, tvb, 3, 1, ENC_BIG_ENDIAN);
337
338                 /*TLVs...*/
339                 pos = 4;
340                 while (pos < len)
341                 {
342                         type = tvb_get_guint8 (tvb, pos);
343                         length = tvb_get_guint8 (tvb, pos + 1);
344                         tlv_item = proto_tree_add_text (mdd_tree, tvb, pos, length + 2,"%s", val_to_str(type, mdd_tlv_vals, "Unknown TLV (%u)"));
345                         tlv_tree = proto_item_add_subtree (tlv_item, ett_tlv);
346
347                         switch(type) {
348
349                                 case DOWNSTREAM_ACTIVE_CHANNEL_LIST:
350                                         subpos = pos + 2;
351                                         while (subpos < pos + length + 2) {
352                                                 subtype = tvb_get_guint8 (tvb, subpos);
353                                                 sublength = tvb_get_guint8 (tvb, subpos + 1);
354                                                 switch(subtype) {
355                                                         case DOWNSTREAM_ACTIVE_CHANNEL_LIST_CHANNEL_ID:
356                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_downstream_active_channel_list_channel_id, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
357                                                                 break;
358                                                         case DOWNSTREAM_ACTIVE_CHANNEL_LIST_FREQUENCY:
359                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_downstream_active_channel_list_frequency, tvb, subpos + 2 , 4, ENC_BIG_ENDIAN);
360                                                                 break;
361                                                         case DOWNSTREAM_ACTIVE_CHANNEL_LIST_MODULATION_ORDER_ANNEX:
362                                                                 tlv_sub_item = proto_tree_add_text (tlv_tree, tvb, subpos + 2, 1, "Modulation Order/Annex");
363                                                                 tlv_sub_tree = proto_item_add_subtree (tlv_sub_item, ett_sub_tlv);
364                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_downstream_active_channel_list_modulation_order, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
365                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_downstream_active_channel_list_annex, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
366                                                                 break;
367                                                         case DOWNSTREAM_ACTIVE_CHANNEL_LIST_PRIMARY_CAPABLE:
368                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_downstream_active_channel_list_primary_capable, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
369                                                                 break;
370                                                         case DOWNSTREAM_ACTIVE_CHANNEL_LIST_CM_STATUS_EVENT_ENABLE_BITMASK:
371                                                                 tlv_sub_item = proto_tree_add_text (tlv_tree, tvb, subpos + 2, 2, "CM-STATUS Event Enable Bitmask");
372                                                                 tlv_sub_tree = proto_item_add_subtree (tlv_sub_item, ett_sub_tlv);
373                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_bitmask_mdd_timeout, tvb, subpos + 2 , 2,ENC_BIG_ENDIAN);
374                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_bitmask_qam_fec_lock_failure, tvb, subpos + 2 , 2, ENC_BIG_ENDIAN);
375                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_bitmask_mdd_recovery, tvb, subpos + 2 , 2,ENC_BIG_ENDIAN);
376                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_bitmask_qam_fec_lock_recovery, tvb, subpos + 2 , 2, ENC_BIG_ENDIAN);
377                                                                 break;
378                                                 }
379                                                 subpos += sublength + 2;
380                                         }
381                                         break;
382                                 case MAC_DOMAIN_DOWNSTREAM_SERVICE_GROUP:
383                                         subpos = pos + 2;
384                                         while (subpos < pos + length + 2) {
385                                                 subtype = tvb_get_guint8 (tvb, subpos);
386                                                 sublength = tvb_get_guint8 (tvb, subpos + 1);
387                                                 switch(subtype) {
388                                                         case MAC_DOMAIN_DOWNSTREAM_SERVICE_GROUP_MD_DS_SG_IDENTIFIER:
389                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_mac_domain_downstream_service_group_md_ds_sg_identifier, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
390                                                                 break;
391                                                         case MAC_DOMAIN_DOWNSTREAM_SERVICE_GROUP_CHANNEL_IDS:
392                                                                 for (i = 0; i < sublength; i++) {
393                                                                         proto_tree_add_item (tlv_tree, hf_docsis_mdd_mac_domain_downstream_service_group_channel_id, tvb, subpos + 2 + i , 1, ENC_BIG_ENDIAN);
394                                                                 }
395                                                                 break;
396                                                 }
397                                                 subpos += sublength + 2;
398                                         }
399                                         break;
400                                 case DOWNSTREAM_AMBIGUITY_RESOLUTION_FREQUENCY_LIST:
401                                         subpos = pos + 2;
402                                         for (i = 0; i < length; i+=4) {
403                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_downstream_ambiguity_resolution_frequency, tvb, subpos + i , 4, ENC_BIG_ENDIAN);
404                                         }
405                                         break;
406                                 case RECEIVE_CHANNEL_PROFILE_REPORTING_CONTROL:
407                                         subpos = pos + 2;
408                                         while (subpos < pos + length + 2) {
409                                                 subtype = tvb_get_guint8 (tvb, subpos);
410                                                 sublength = tvb_get_guint8 (tvb, subpos + 1);
411                                                 switch(subtype) {
412                                                         case RCP_CENTER_FREQUENCY_SPACING:
413                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_rpc_center_frequency_spacing, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
414                                                                 break;
415                                                         case VERBOSE_RCP_REPORTING:
416                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_verbose_rcp_reporting, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
417                                                                 break;
418                                                 }
419                                                 subpos += sublength + 2;
420                                         }
421                                         break;
422                                 case IP_INITIALIZATION_PARAMETERS:
423                                         subpos = pos + 2;
424                                         while (subpos < pos + length + 2) {
425                                                 subtype = tvb_get_guint8 (tvb, subpos);
426                                                 sublength = tvb_get_guint8 (tvb, subpos + 1);
427                                                 switch(subtype) {
428                                                         case IP_PROVISIONING_MODE:
429                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_ip_provisioning_mode, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
430                                                                 break;
431                                                         case PRE_REGISTRATION_DSID:
432                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_pre_registration_dsid, tvb, subpos + 2 , 3, ENC_BIG_ENDIAN);
433                                                                 break;
434                                                 }
435                                                 subpos += sublength + 2;
436                                         }
437                                         break;
438                                 case EARLY_AUTHENTICATION_AND_ENCRYPTION:
439                                         subpos = pos + 2;
440                                         proto_tree_add_item (tlv_tree, hf_docsis_mdd_early_authentication_and_encryption, tvb, subpos, 1, ENC_BIG_ENDIAN);
441                                         break;
442                                 case UPSTREAM_ACTIVE_CHANNEL_LIST:
443                                         subpos = pos + 2;
444                                         while (subpos < pos + length + 2) {
445                                                 subtype = tvb_get_guint8 (tvb, subpos);
446                                                 sublength = tvb_get_guint8 (tvb, subpos + 1);
447                                                 switch(subtype) {
448                                                         case UPSTREAM_ACTIVE_CHANNEL_LIST_UPSTREAM_CHANNEL_ID:
449                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_upstream_active_channel_list_upstream_channel_id, tvb, subpos + 2 , 1, ENC_BIG_ENDIAN);
450                                                                 break;
451                                                         case UPSTREAM_ACTIVE_CHANNEL_LIST_CM_STATUS_EVENT_ENABLE_BITMASK:
452                                                                 tlv_sub_item = proto_tree_add_text (tlv_tree, tvb, subpos + 2, 2, "CM-STATUS Event Enable Bitmask");
453                                                                 tlv_sub_tree = proto_item_add_subtree (tlv_sub_item, ett_sub_tlv);
454                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_bitmask_t4_timeout, tvb, subpos + 2 , 2, ENC_BIG_ENDIAN);
455                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_bitmask_t3_retries_exceeded, tvb, subpos + 2 , 2, ENC_BIG_ENDIAN);
456                                                                 proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_bitmask_successful_ranging_after_t3_retries_exceeded, tvb, subpos + 2 , 2, ENC_BIG_ENDIAN);
457                                                                 break;
458                                                 }
459                                                 subpos += sublength + 2;
460                                         }
461                                         break;
462                                 case UPSTREAM_AMBIGUITY_RESOLUTION_CHANNEL_LIST:
463                                         sublength = tvb_get_guint8 (tvb, subpos + 1);
464                                         for (i = 0; i < sublength; i++) {
465                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_upstream_ambiguity_resolution_channel_list_channel_id, tvb, pos + 2 + i , 1, ENC_BIG_ENDIAN);
466                                         }
467                                         break;
468                                 case UPSTREAM_FREQUENCY_RANGE:
469                                         subpos = pos + 2;
470                                         proto_tree_add_item (tlv_tree, hf_docsis_mdd_upstream_frequency_range, tvb, subpos, 1, ENC_BIG_ENDIAN);
471                                         break;
472                                 case SYMBOL_CLOCK_LOCKING_INDICATOR:
473                                         subpos = pos + 2;
474                                         proto_tree_add_item (tlv_tree, hf_docsis_mdd_symbol_clock_locking_indicator, tvb, subpos, 1, ENC_BIG_ENDIAN);
475                                         break;
476                                 case CM_STATUS_EVENT_CONTROL:
477                                         subpos = pos + 2;
478                                         while (subpos < pos + length + 2) {
479                                                 subtype = tvb_get_guint8 (tvb, subpos);
480                                                 sublength = tvb_get_guint8 (tvb, subpos + 1);
481                                                 switch(subtype) {
482                                                         case EVENT_TYPE_CODE:
483                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_event_type, tvb, subpos+2, 1, ENC_BIG_ENDIAN);
484                                                                 break;
485                                                         case MAXIMUM_EVENT_HOLDOFF_TIMER:
486                                                                 text_item = proto_tree_add_item (tlv_tree, hf_docsis_mdd_maximum_event_holdoff_timer, tvb, subpos, 2, ENC_BIG_ENDIAN);
487                                                                 proto_item_append_text(text_item, " (%d ms)", (256*tvb_get_guint8 (tvb, subpos) + tvb_get_guint8 (tvb, subpos + 1)) * 20);
488                                                                 break;
489                                                         case MAXIMUM_NUMBER_OF_REPORTS_PER_EVENT:
490                                                                 text_item = proto_tree_add_item (tlv_tree, hf_docsis_mdd_maximum_number_of_reports_per_event, tvb, subpos, 1, ENC_BIG_ENDIAN);
491                                                                 if ( tvb_get_guint8 (tvb, subpos) == 0) {
492                                                                         proto_item_append_text(text_item, " (Unlimited)");
493                                                                 }
494                                                                 break;
495                                                 }
496                                                 subpos += sublength + 2;
497                                         }
498                                         break;
499                                 case UPSTREAM_TRANSMIT_POWER_REPORTING:
500                                         subpos = pos + 2;
501                                         proto_tree_add_item (tlv_tree, hf_docsis_mdd_upstream_transmit_power_reporting, tvb, subpos, 1, ENC_BIG_ENDIAN);
502                                         break;
503                                 case DSG_DA_TO_DSID_ASSOCIATION_ENTRY:
504                                         subpos = pos + 2;
505                                         while (subpos < pos + length + 2) {
506                                                 subtype = tvb_get_guint8 (tvb, subpos);
507                                                 sublength = tvb_get_guint8 (tvb, subpos + 1);
508                                                 switch(subtype) {
509                                                         case DSG_DA_TO_DSID_ASSOCIATION_DA:
510                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_dsg_da_to_dsid_association_da, tvb, subpos, 6, ENC_BIG_ENDIAN);
511                                                                 break;
512                                                         case DSG_DA_TO_DSID_ASSOCIATION_DSID:
513                                                                 proto_tree_add_item (tlv_tree, hf_docsis_mdd_dsg_da_to_dsid_association_dsid, tvb, subpos, 3, ENC_BIG_ENDIAN);
514                                                                 break;
515                                                 }
516                                                 subpos += sublength + 2;
517                                         }
518                                         break;
519                                 case CM_STATUS_EVENT_ENABLE_NON_CHANNEL_SPECIFIC_EVENTS:
520                                         subpos = pos + 2;
521                                         tlv_sub_item = proto_tree_add_text (tlv_tree, tvb, subpos, 2, "CM-STATUS Event Enable Bitmask for Non-Channel-Specific Events");
522                                         tlv_sub_tree = proto_item_add_subtree (tlv_sub_item, ett_sub_tlv);
523                                         proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_sequence_out_of_range, tvb, subpos, 2,ENC_BIG_ENDIAN);
524                                         proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_cm_operating_on_battery_backup, tvb, subpos , 2,ENC_BIG_ENDIAN);
525                                         proto_tree_add_item (tlv_sub_tree, hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_cm_returned_to_ac_power, tvb, subpos , 2,ENC_BIG_ENDIAN);
526                                         break;
527                         }
528                         pos += length + 2;
529                 }
530         }                               /* if(tree) */
531 }
532
533
534
535
536 /* Register the protocol with Wireshark */
537
538 /* this format is require because a script is used to build the C function
539    that calls all the protocol registration.
540 */
541
542
543 void proto_register_docsis_mdd (void)
544 {
545         /* Setup list of header fields  See Section 1.6.1 for details*/
546         static hf_register_info hf[] = {
547                 {&hf_docsis_mdd_ccc,
548                 {"Configuration Change Count", "docsis_mdd.ccc",
549                 FT_UINT8, BASE_DEC, NULL, 0x0,
550                 "Mdd Configuration Change Count", HFILL}
551                 },
552                 {&hf_docsis_mdd_number_of_fragments,
553                 {"Number of Fragments", "docsis_mdd.number_of_fragments",
554                 FT_UINT8, BASE_DEC, NULL, 0x0,
555                 "Mdd Number of Fragments", HFILL}
556                 },
557                 {&hf_docsis_mdd_fragment_sequence_number,
558                 {"Fragment Sequence Number", "docsis_mdd.fragment_sequence_number",
559                 FT_UINT8, BASE_DEC, NULL, 0x0,
560                 "Mdd Fragment Sequence Number", HFILL}
561                 },
562                 {&hf_docsis_mdd_current_channel_dcid,
563                 {"Current Channel DCID", "docsis_mdd.current_channel_dcid",
564                 FT_UINT8, BASE_DEC, NULL, 0x0,
565                 "Mdd Current Channel DCID", HFILL}
566                 },
567                 {&hf_docsis_mdd_downstream_active_channel_list_channel_id,
568                 {"Channel ID", "docsis_mdd.downstream_active_channel_list_channel_id",
569                 FT_UINT8, BASE_DEC, NULL, 0x0,
570                 "Mdd Downstream Active Channel List Channel ID", HFILL}
571                 },
572                 {&hf_docsis_mdd_downstream_active_channel_list_frequency,
573                 {"Frequency", "docsis_mdd.downstream_active_channel_list_frequency",
574                 FT_UINT32, BASE_DEC, NULL, 0x0,
575                 "Mdd Downstream Active Channel List Frequency", HFILL}
576                 },
577                 {&hf_docsis_mdd_downstream_active_channel_list_annex,
578                 {"Annex", "docsis_mdd.downstream_active_channel_list_annex",
579                 FT_UINT8, BASE_DEC, VALS(J83_annex_vals), 0xF0,
580                 "Mdd Downstream Active Channel List Annex", HFILL}
581                 },
582                 {&hf_docsis_mdd_downstream_active_channel_list_modulation_order,
583                 {"Modulation Order", "docsis_mdd.downstream_active_channel_list_modulation_order",
584                 FT_UINT8, BASE_DEC, VALS(modulation_order_vals), 0x0F,
585                 "Mdd Downstream Active Channel List Modulation Order", HFILL}
586                 },
587                 {&hf_docsis_mdd_downstream_active_channel_list_primary_capable,
588                 {"Primary Capable", "docsis_mdd.downstream_active_channel_list_primary_capable",
589                 FT_UINT8, BASE_DEC, VALS(primary_capable_vals), 0x0,
590                 "Mdd Downstream Active Channel List Primary Capable", HFILL}
591                 },
592                 {&hf_docsis_mdd_cm_status_event_enable_bitmask_mdd_timeout,
593                 {"MDD Timeout", "docsis_mdd.downstream_active_channel_list_mdd_timeout",
594                 FT_UINT16, BASE_DEC, NULL, 0x0002,
595                 "Mdd Downstream Active Channel List MDD Timeout", HFILL}
596                 },
597                 {&hf_docsis_mdd_cm_status_event_enable_bitmask_qam_fec_lock_failure,
598                 {"QAM/FEC Lock Failure", "docsis_mdd.cm_status_event_enable_bitmask_qam_fec_lock_failure",
599                 FT_UINT16, BASE_DEC, NULL, 0x0004,
600                 "Mdd Downstream Active Channel List QAM/FEC Lock Failure", HFILL}
601                 },
602                 {&hf_docsis_mdd_cm_status_event_enable_bitmask_mdd_recovery,
603                 {"MDD Recovery", "docsis_mdd.cm_status_event_enable_bitmask_mdd_recovery",
604                 FT_UINT16, BASE_DEC, NULL, 0x0010,
605                 "CM-STATUS event MDD Recovery", HFILL}
606                 },
607                 {&hf_docsis_mdd_cm_status_event_enable_bitmask_qam_fec_lock_recovery,
608                 {"QAM/FEC Lock Recovery", "docsis_mdd.cm_status_event_enable_bitmask_qam_fec_lock_recovery",
609                 FT_UINT16, BASE_DEC, NULL, 0x0020,
610                 "CM-STATUS event QAM/FEC Lock Recovery", HFILL}
611                 },
612                 {&hf_docsis_mdd_cm_status_event_enable_bitmask_t4_timeout,
613                 {"T4 timeout", "docsis_mdd.cm_status_event_enable_bitmask_t4_timeout",
614                 FT_UINT16, BASE_DEC, NULL, 0x0040,
615                 "CM-STATUS event T4 timeout", HFILL}
616                 },
617                 {&hf_docsis_mdd_cm_status_event_enable_bitmask_t3_retries_exceeded,
618                 {"T3 Retries Exceeded", "docsis_mdd.cm_status_event_enable_bitmask_t3_retries_exceeded",
619                 FT_UINT16, BASE_DEC, NULL, 0x0080,
620                 "CM-STATUS event T3 Retries Exceeded", HFILL}
621                 },
622                 {&hf_docsis_mdd_cm_status_event_enable_bitmask_successful_ranging_after_t3_retries_exceeded,
623                 {"Successful Ranging after T3 Retries Exceeded", "docsis_mdd.cm_status_event_enable_bitmask_successful_ranging_after_t3_retries_exceeded",
624                 FT_UINT16, BASE_DEC, NULL, 0x0100,
625                 "CM-STATUS event Successful Ranging after T3 Retries Exceeded", HFILL}
626                 },
627                 {&hf_docsis_mdd_mac_domain_downstream_service_group_channel_id,
628                 {"Channel Id", "docsis_mdd.mac_domain_downstream_service_group_channel_id",
629                 FT_UINT8, BASE_DEC, NULL, 0x0,
630                 "Mdd Mac Domain Downstream Service Group Channel Id", HFILL}
631                 },
632                 {&hf_docsis_mdd_mac_domain_downstream_service_group_md_ds_sg_identifier,
633                 {"MD-DS-SG Identifier", "docsis_mdd.mac_domain_downstream_service_group_md_ds_sg_identifier",
634                 FT_UINT8, BASE_DEC, NULL, 0x0,
635                 "Mdd Mac Domain Downstream Service Group MD-DS-SG Identifier", HFILL}
636                 },
637                 {&hf_docsis_mdd_downstream_ambiguity_resolution_frequency,
638                 {"Frequency", "docsis_mdd.downstream_ambiguity_resolution_frequency",
639                 FT_UINT32, BASE_DEC, NULL, 0x0,
640                 "Mdd Downstream Ambiguity Resolution frequency", HFILL}
641                 },
642                 {&hf_docsis_mdd_rpc_center_frequency_spacing,
643                 {"RPC Center Frequency Spacing", "docsis_mdd.rpc_center_frequency_spacing",
644                 FT_UINT8, BASE_DEC, VALS(rpc_center_frequency_spacing_vals), 0x0,
645                 "Mdd RPC Center Frequency Spacing", HFILL}
646                 },
647                 {&hf_docsis_mdd_verbose_rcp_reporting,
648                 {"Verbose RCP reporting", "docsis_mdd.verbose_rpc_reporting",
649                 FT_UINT8, BASE_DEC, VALS(verbose_rpc_reporting_vals), 0x0,
650                 "Mdd Verbose RPC Reporting", HFILL}
651                 },
652                 {&hf_docsis_mdd_ip_provisioning_mode,
653                 {"IP Provisioning Mode", "docsis_mdd.ip_provisioning_mode",
654                 FT_UINT8, BASE_DEC, VALS(ip_provisioning_mode_vals), 0x0,
655                 "Mdd IP Provisioning Mode", HFILL}
656                 },
657                 {&hf_docsis_mdd_pre_registration_dsid,
658                 {"Pre-registration DSID", "docsis_mdd.pre_registration_dsid",
659                 FT_UINT24, BASE_DEC, NULL, 0x0FFFFF,
660                 "Mdd Pre-registration DSID", HFILL}
661                 },
662                 {&hf_docsis_mdd_early_authentication_and_encryption,
663                 {"Early Authentication and Encryption", "docsis_mdd.early_authentication_and_encryption",
664                 FT_UINT8, BASE_DEC, VALS(eae_vals), 0x0,
665                 "Mdd Early Authentication and Encryption", HFILL}
666                 },
667                 {&hf_docsis_mdd_upstream_active_channel_list_upstream_channel_id,
668                 {"Upstream Channel Id", "docsis_mdd.upstream_active_channel_list_upstream_channel_id",
669                 FT_UINT8, BASE_DEC, NULL, 0x0,
670                 "Mdd Upstream Active Channel List Upstream Channel Id", HFILL}
671                 },
672                 {&hf_docsis_mdd_upstream_ambiguity_resolution_channel_list_channel_id,
673                 {"Channel Id", "docsis_mdd.upstream_ambiguity_resolution_channel_list_channel_id",
674                 FT_UINT8, BASE_DEC, NULL, 0x0,
675                 "Mdd Mac Domain Upstream Ambiguity Resolution Channel List Channel Id", HFILL}
676                 },
677                 {&hf_docsis_mdd_upstream_frequency_range,
678                 {"Upstream Frequency Range", "docsis_mdd.upstream_frequency_range",
679                 FT_UINT8, BASE_DEC, VALS(upstream_frequency_range_vals), 0x0,
680                 "Mdd Upstream Frequency Range", HFILL}
681                 },
682                 {&hf_docsis_mdd_symbol_clock_locking_indicator,
683                 {"Symbol Clock Locking Indicator", "docsis_mdd.symbol_clock_locking_indicator",
684                 FT_UINT8, BASE_DEC, VALS(symbol_clock_locking_indicator_vals), 0x0,
685                 "Mdd Symbol Clock Locking Indicator", HFILL}
686                 },
687                 {&hf_docsis_mdd_event_type,
688                 {"Event Type", "docsis_mdd.event_type",
689                 FT_UINT8, BASE_DEC, VALS(symbol_cm_status_event_vals), 0x0,
690                 "Mdd CM-STATUS Event Type", HFILL}
691                 },
692                 {&hf_docsis_mdd_maximum_event_holdoff_timer,
693                 {"Maximum Event Holdoff Timer (units of 20 ms)", "docsis_mdd.maximum_event_holdoff_timer",
694                 FT_UINT16, BASE_DEC, NULL, 0x0,
695                 "Mdd Maximum Event Holdoff Timer", HFILL}
696                 },
697                 {&hf_docsis_mdd_maximum_number_of_reports_per_event,
698                 {"Maximum Number of Reports per Event", "docsis_mdd.maximum_number_of_reports_per_event",
699                 FT_UINT8, BASE_DEC, NULL, 0x0,
700                 "Mdd Maximum Number of Reports per Event", HFILL}
701                 },
702                 {&hf_docsis_mdd_upstream_transmit_power_reporting,
703                 {"Upstream Transmit Power Reporting", "docsis_mdd.upstream_transmit_power_reporting",
704                 FT_UINT8, BASE_DEC, VALS(upstream_transmit_power_reporting_vals), 0x0,
705                 "Mdd Upstream Transmit Power Reporting", HFILL}
706                 },
707                 {&hf_docsis_mdd_dsg_da_to_dsid_association_da,
708                 {"Destination Address", "docsis_mdd.dsg_da_to_dsid_association_da",
709                 FT_UINT8, BASE_HEX, NULL, 0x0,
710                 "Mdd DSG DA to DSID association Destination Address", HFILL}
711                 },
712                 {&hf_docsis_mdd_dsg_da_to_dsid_association_dsid,
713                 {"DSID", "docsis_mdd.dsg_da_to_dsid_association_dsid",
714                 FT_UINT24, BASE_DEC, NULL, 0x0FFFFF,
715                 "Mdd Mdd DSG DA to DSID association DSID", HFILL}
716                 },
717                 {&hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_sequence_out_of_range,
718                 {"Sequence out of range", "docsis_mdd.cm_status_event_enable_non_channel_specific_events_sequence_out_of_range",
719                 FT_UINT16, BASE_DEC, NULL, 0x0008,
720                 "CM-STATUS event non-channel-event Sequence out of range", HFILL}
721                 },
722                 {&hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_cm_operating_on_battery_backup,
723                 {"CM operating on battery backup", "docsis_mdd.cm_status_event_enable_non_channel_specific_events_cm_operating_on_battery_backup",
724                 FT_UINT16, BASE_DEC, NULL, 0x0200,
725                 "CM-STATUS event non-channel-event Cm operating on battery backup", HFILL}
726                 },
727                 {&hf_docsis_mdd_cm_status_event_enable_non_channel_specific_events_cm_returned_to_ac_power,
728                 {"Returned to AC power", "docsis_mdd.cm_status_event_enable_non_channel_specific_events_cm_returned_to_ac_power",
729                 FT_UINT16, BASE_DEC, NULL, 0x0400,
730                 "CM-STATUS event non-channel-event Cm returned to AC power", HFILL}
731                 },
732
733         };
734
735         /* Setup protocol subtree array */
736         static gint *ett[] = {
737                 &ett_docsis_mdd,
738                 &ett_tlv,
739                 &ett_sub_tlv
740         };
741
742         /* Register the protocol name and description */
743         proto_docsis_mdd =
744                 proto_register_protocol ("DOCSIS Mac Domain Description",
745                                         "DOCSIS Mdd", "docsis_mdd");
746
747         /* Required function calls to register the header fields and subtrees used */
748         proto_register_field_array (proto_docsis_mdd, hf, array_length (hf));
749         proto_register_subtree_array (ett, array_length (ett));
750
751         register_dissector ("docsis_mdd", dissect_mdd, proto_docsis_mdd);
752 }
753
754
755 /* If this dissector uses sub-dissector registration add a registration routine.
756    This format is required because a script is used to find these routines and
757    create the code that calls these routines.
758 */
759 void
760 proto_reg_handoff_docsis_mdd (void)
761 {
762         dissector_handle_t docsis_mdd_handle;
763
764         docsis_mdd_handle = find_dissector ("docsis_mdd");
765         dissector_add_uint ("docsis_mgmt", 33, docsis_mdd_handle);
766 }