Use ENC_NA as proto_tree_add_item() encoding arg for FT_ETHER hf[] field type.
[obnox/wireshark/wip.git] / plugins / docsis / packet-tlv.c
1 /* packet-tlv.c
2  * Routines to Dissect Appendix C TLV's
3  * Copyright 2002, Anand V. Narwani <anand[AT]narwani.org>
4  *
5  * $Id$
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 #include "packet-tlv.h"
32
33 /* This module will dissect the Appendix C TLV's.  Please see:
34  * http://www.cablemodem.com/specifications/specifications.html
35  *
36  * The main dissector is dissect_tlv.  This routine will dissect
37  * top level TLV's and call sub-dissectors for the sub-TLV's.
38  */
39
40 /* Initialize the protocol and registered fields */
41 static dissector_handle_t docsis_vsif_handle;
42 static dissector_handle_t docsis_ucd_handle;
43
44
45 static int proto_docsis_tlv = -1;
46 static int hf_docsis_tlv_down_freq = -1;
47 static int hf_docsis_tlv_upstream_chid = -1;
48 static int hf_docsis_tlv_net_access = -1;
49 static int hf_docsis_tlv_cos = -1;
50 static int hf_docsis_tlv_mcap = -1;
51 static int hf_docsis_tlv_privacy_enable = -1;
52 static int hf_docsis_tlv_max_cpe = -1;
53 static int hf_docsis_tlv_max_classifiers = -1;
54 static int hf_docsis_tlv_snmp_access = -1;
55 static int hf_docsis_tlv_snmp_obj = -1;
56 static int hf_docsis_tlv_svc_unavail = -1;
57 static int hf_docsis_tlv_svc_unavail_classid = -1;
58 static int hf_docsis_tlv_svc_unavail_type = -1;
59 static int hf_docsis_tlv_svc_unavail_code = -1;
60 static int hf_docsis_tlv_bpi = -1;
61 static int hf_docsis_tlv_phs = -1;
62 static int hf_docsis_tlv_hmac_digest = -1;
63 static int hf_docsis_tlv_tftp_server_timestamp = -1;
64 static int hf_docsis_tlv_tftp_prov_modem_address = -1;
65 static int hf_docsis_tlv_upclsfr = -1;
66 static int hf_docsis_tlv_downclsfr = -1;
67 static int hf_docsis_tlv_upsflow = -1;
68 static int hf_docsis_tlv_downsflow = -1;
69 static int hf_docsis_tlv_vendor_spec = -1;
70 static int hf_docsis_tlv_cm_mic = -1;
71 static int hf_docsis_tlv_cmts_mic = -1;
72 static int hf_docsis_tlv_auth_block = -1;
73 static int hf_docsis_tlv_key_seq_num = -1;
74 static int hf_docsis_tlv_snmpv3_kick = -1;
75 static int hf_docsis_tlv_snmpv3_kick_name = -1;
76 static int hf_docsis_tlv_snmpv3_kick_publicnum = -1;
77 static int hf_docsis_tlv_mfgr_cvc = -1;
78 static int hf_docsis_tlv_cosign_cvc = -1;
79 static int hf_docsis_tlv_vendor_id = -1;
80 static int hf_docsis_tlv_sw_file = -1;
81 static int hf_docsis_tlv_sw_upg_srvr = -1;
82 static int hf_docsis_tlv_cpe_ethernet = -1;
83 static int hf_docsis_tlv_modem_addr = -1;
84 static int hf_docsis_tlv_rng_tech = -1;
85 static int hf_docsis_tlv_subs_mgmt_ctrl = -1;
86 static int hf_docsis_tlv_subs_mgmt_ip_table = -1;
87 static int hf_docsis_tlv_subs_mgmt_ip_entry = -1;
88 static int hf_docsis_tlv_subs_mgmt_filter_grps = -1;
89 static int hf_docsis_tlv_snmpv3_ntfy_rcvr = -1;
90 static int hf_docsis_tlv_enable_20_mode = -1;
91 static int hf_docsis_tlv_enable_test_modes = -1;
92 static int hf_docsis_tlv_ds_ch_list = -1;
93 static int hf_docsis_tlv_mc_mac_address = -1;
94 static int hf_docsis_tlv_dut_filter = -1;
95 static int hf_docsis_tlv_tcc = -1;
96 static int hf_docsis_tlv_sid_cl = -1;
97 static int hf_docsis_tlv_rcp = -1;
98 static int hf_docsis_tlv_rcc = -1;
99 static int hf_docsis_tlv_dsid = -1;
100 static int hf_docsis_tlv_sec_assoc = -1;
101 static int hf_docsis_tlv_init_ch_timeout = -1;
102 static int hf_docsis_tlv_ch_asgn = -1;
103 static int hf_docsis_tlv_cm_init_reason = -1;
104 static int hf_docsis_tlv_sw_upg_srvr_ipv6 = -1;
105 static int hf_docsis_tlv_tftp_prov_cm_ipv6_addr = -1;
106 static int hf_docsis_tlv_us_drop_clfy = -1;
107 static int hf_docsis_tlv_subs_mgmt_ipv6_lst = -1;
108 static int hf_docsis_tlv_us_drop_clfy_group_id = -1;
109 static int hf_docsis_tlv_subs_mgmt_ctrl_max_cpe_ipv6 = -1;
110 static int hf_docsis_tlv_cmts_mc_sess_enc = -1;
111
112 static int hf_docsis_tlv_cos_id = -1;
113 static int hf_docsis_tlv_cos_sid = -1;
114 static int hf_docsis_tlv_cos_max_down = -1;
115 static int hf_docsis_tlv_cos_max_up = -1;
116 static int hf_docsis_tlv_cos_up_chnl_pri = -1;
117 static int hf_docsis_tlv_cos_min_grntd_up = -1;
118 static int hf_docsis_tlv_cos_max_up_burst = -1;
119 static int hf_docsis_tlv_cos_privacy_enable = -1;
120
121 static int hf_docsis_tlv_mcap_concat = -1;
122 static int hf_docsis_tlv_mcap_docs_ver = -1;
123 static int hf_docsis_tlv_mcap_frag = -1;
124 static int hf_docsis_tlv_mcap_phs = -1;
125 static int hf_docsis_tlv_mcap_igmp = -1;
126 static int hf_docsis_tlv_mcap_down_said = -1;
127 static int hf_docsis_tlv_mcap_up_sid = -1;
128 static int hf_docsis_tlv_mcap_privacy = -1;
129 static int hf_docsis_tlv_mcap_8021P_filter = -1;
130 static int hf_docsis_tlv_mcap_8021Q_filter = -1;
131 static int hf_docsis_tlv_mcap_xmit_eq_taps_per_sym = -1;
132 static int hf_docsis_tlv_mcap_xmit_eq_taps = -1;
133 static int hf_docsis_tlv_mcap_dcc = -1;
134 static int hf_docsis_tlv_mcap_ip_filters = -1;
135 static int hf_docsis_tlv_mcap_llc_filters = -1;
136 static int hf_docsis_tlv_mcap_exp_unicast_sid = -1;
137 static int hf_docsis_tlv_mcap_rnghoff_cm = -1;
138 static int hf_docsis_tlv_mcap_rnghoff_erouter = -1;
139 static int hf_docsis_tlv_mcap_rnghoff_emta = -1;
140 static int hf_docsis_tlv_mcap_rnghoff_estb = -1;
141 static int hf_docsis_tlv_mcap_l2vpn = -1;
142 static int hf_docsis_tlv_mcap_l2vpn_esafe = -1;
143 static int hf_docsis_tlv_mcap_dut_filtering = -1;
144 static int hf_docsis_tlv_mcap_us_freq_range = -1;
145 static int hf_docsis_tlv_mcap_us_srate_160 = -1;
146 static int hf_docsis_tlv_mcap_us_srate_320 = -1;
147 static int hf_docsis_tlv_mcap_us_srate_640 = -1;
148 static int hf_docsis_tlv_mcap_us_srate_1280 = -1;
149 static int hf_docsis_tlv_mcap_us_srate_2560 = -1;
150 static int hf_docsis_tlv_mcap_us_srate_5120 = -1;
151 static int hf_docsis_tlv_mcap_sac = -1;
152 static int hf_docsis_tlv_mcap_code_hop_mode2 = -1;
153 static int hf_docsis_tlv_mcap_mtc = -1;
154 static int hf_docsis_tlv_mcap_512_msps_utc = -1;
155 static int hf_docsis_tlv_mcap_256_msps_utc = -1;
156 static int hf_docsis_tlv_mcap_total_sid_cluster = -1;
157 static int hf_docsis_tlv_mcap_sid_per_sf = -1;
158 static int hf_docsis_tlv_mcap_mrc = -1;
159 static int hf_docsis_tlv_mcap_total_dsid = -1;
160 static int hf_docsis_tlv_mcap_reseq_dsid = -1;
161 static int hf_docsis_tlv_mcap_mc_dsid = -1;
162 static int hf_docsis_tlv_mcap_mc_dsid_fwd = -1;
163 static int hf_docsis_tlv_mcap_fctype_fwd = -1;
164 static int hf_docsis_tlv_mcap_dpv_path = -1;
165 static int hf_docsis_tlv_mcap_dpv_packet = -1;
166 static int hf_docsis_tlv_mcap_ugs = -1;
167 static int hf_docsis_tlv_mcap_map_ucd = -1;
168 static int hf_docsis_tlv_mcap_udc = -1;
169 static int hf_docsis_tlv_mcap_ipv6 = -1;
170 static int hf_docsis_tlv_mcap_ext_us_trans_power = -1;
171
172
173 static int hf_docsis_tlv_clsfr_ref = -1;
174 static int hf_docsis_tlv_clsfr_id = -1;
175 static int hf_docsis_tlv_clsfr_sflow_ref = -1;
176 static int hf_docsis_tlv_clsfr_sflow_id = -1;
177 static int hf_docsis_tlv_clsfr_rule_pri = -1;
178 static int hf_docsis_tlv_clsfr_act_state = -1;
179 static int hf_docsis_tlv_clsfr_dsc_act = -1;
180 static int hf_docsis_tlv_clsfr_err = -1;
181 static int hf_docsis_tlv_ipclsfr = -1;
182 static int hf_docsis_tlv_ethclsfr = -1;
183 static int hf_docsis_tlv_dot1qclsfr = -1;
184
185 static int hf_docsis_tlv_clsfr_vendor_spc = -1;
186
187 static int hf_docsis_tlv_clsfr_err_param = -1;
188 static int hf_docsis_tlv_clsfr_err_code = -1;
189 static int hf_docsis_tlv_clsfr_err_msg = -1;
190
191 static int hf_docsis_tlv_ipclsfr_tosmask = -1;
192 static int hf_docsis_tlv_ipclsfr_ipproto = -1;
193 static int hf_docsis_tlv_ipclsfr_src = -1;
194 static int hf_docsis_tlv_ipclsfr_dst = -1;
195 static int hf_docsis_tlv_ipclsfr_srcmask = -1;
196 static int hf_docsis_tlv_ipclsfr_dstmask = -1;
197 static int hf_docsis_tlv_ipclsfr_sport_start = -1;
198 static int hf_docsis_tlv_ipclsfr_sport_end = -1;
199 static int hf_docsis_tlv_ipclsfr_dport_start = -1;
200 static int hf_docsis_tlv_ipclsfr_dport_end = -1;
201
202 static int hf_docsis_tlv_ethclsfr_dmac = -1;
203 static int hf_docsis_tlv_ethclsfr_smac = -1;
204 static int hf_docsis_tlv_ethclsfr_ethertype = -1;
205
206 static int hf_docsis_tlv_dot1qclsfr_user_pri = -1;
207 static int hf_docsis_tlv_dot1qclsfr_vlanid = -1;
208 static int hf_docsis_tlv_dot1qclsfr_vendorspec = -1;
209
210 static int hf_docsis_tlv_sflow_ref = -1;
211 static int hf_docsis_tlv_sflow_id = -1;
212 static int hf_docsis_tlv_sflow_sid = -1;
213 static int hf_docsis_tlv_sflow_classname = -1;
214 static int hf_docsis_tlv_sflow_qos_param = -1;
215 static int hf_docsis_tlv_sflow_err = -1;
216 static int hf_docsis_tlv_sflow_traf_pri = -1;
217 static int hf_docsis_tlv_sflow_max_sus = -1;
218 static int hf_docsis_tlv_sflow_max_burst = -1;
219 static int hf_docsis_tlv_sflow_min_traf = -1;
220 static int hf_docsis_tlv_sflow_ass_min_pkt_size = -1;
221 static int hf_docsis_tlv_sflow_timeout_active = -1;
222 static int hf_docsis_tlv_sflow_timeout_admitted = -1;
223 static int hf_docsis_tlv_sflow_vendor_spec = -1;
224 static int hf_docsis_tlv_sflow_max_concat_burst = -1;
225 static int hf_docsis_tlv_sflow_sched_type = -1;
226 static int hf_docsis_tlv_sflow_reqxmit_pol = -1;
227 static int hf_docsis_tlv_sflow_nominal_polling = -1;
228 static int hf_docsis_tlv_sflow_tolerated_jitter = -1;
229 static int hf_docsis_tlv_sflow_ugs_size = -1;
230 static int hf_docsis_tlv_sflow_nom_grant_intvl = -1;
231 static int hf_docsis_tlv_sflow_tol_grant_jitter = -1;
232 static int hf_docsis_tlv_sflow_grants_per_intvl = -1;
233 static int hf_docsis_tlv_sflow_ip_tos_overwrite = -1;
234 static int hf_docsis_tlv_sflow_ugs_timeref = -1;
235 static int hf_docsis_tlv_sflow_max_down_latency = -1;
236
237 static int hf_docsis_tlv_sflow_err_param = -1;
238 static int hf_docsis_tlv_sflow_err_code = -1;
239 static int hf_docsis_tlv_sflow_err_msg = -1;
240
241 static int hf_docsis_tlv_phs_class_ref = -1;
242 static int hf_docsis_tlv_phs_class_id = -1;
243 static int hf_docsis_tlv_phs_sflow_ref = -1;
244 static int hf_docsis_tlv_phs_sflow_id = -1;
245 static int hf_docsis_tlv_phs_dsc_action = -1;
246 static int hf_docsis_tlv_phs_err = -1;
247 static int hf_docsis_tlv_phs_phsf = -1;
248 static int hf_docsis_tlv_phs_phsm = -1;
249 static int hf_docsis_tlv_phs_phsv = -1;
250 static int hf_docsis_tlv_phs_phsi = -1;
251 static int hf_docsis_tlv_phs_phss = -1;
252 static int hf_docsis_tlv_phs_vendorspec = -1;
253
254 static int hf_docsis_tlv_phs_err_param = -1;
255 static int hf_docsis_tlv_phs_err_code = -1;
256 static int hf_docsis_tlv_phs_err_msg = -1;
257
258 static int hf_docsis_tlv_ds_ch_list_single = -1;
259 static int hf_docsis_tlv_ds_ch_list_range = -1;
260 static int hf_docsis_tlv_ds_ch_list_default_timeout = -1;
261
262 static int hf_docsis_tlv_single_ch_timeout = -1;
263 static int hf_docsis_tlv_single_ch_freq = -1;
264
265 static int hf_docsis_tlv_freq_rng_timeout = -1;
266 static int hf_docsis_tlv_freq_rng_start = -1;
267 static int hf_docsis_tlv_freq_rng_end = -1;
268 static int hf_docsis_tlv_freq_rng_step = -1;
269
270 static int hf_docsis_tlv_dut_filter_control = -1;
271 static int hf_docsis_tlv_dut_filter_cmim = -1;
272
273 static int hf_docsis_tlv_tcc_refid = -1;
274 static int hf_docsis_tlv_tcc_us_ch_action= -1;
275 static int hf_docsis_tlv_tcc_us_ch_id= -1;
276 static int hf_docsis_tlv_tcc_new_us_ch_id= -1;
277 static int hf_docsis_tlv_tcc_ucd = -1;
278 static int hf_docsis_tlv_tcc_rng_sid= -1;
279 static int hf_docsis_tlv_tcc_init_tech= -1;
280 static int hf_docsis_tlv_tcc_rng_parms= -1;
281 static int hf_docsis_tlv_tcc_dyn_rng_win= -1;
282 static int hf_docsis_tlv_tcc_err = -1;
283
284 static int hf_docsis_rng_parms_us_ch_id = -1;
285 static int hf_docsis_rng_parms_time_off_int = -1;
286 static int hf_docsis_rng_parms_time_off_frac = -1;
287 static int hf_docsis_rng_parms_power_off = -1;
288 static int hf_docsis_rng_parms_freq_off = -1;
289
290 static int hf_docsis_tcc_err_subtype = -1;
291 static int hf_docsis_tcc_err_code = -1;
292 static int hf_docsis_tcc_err_msg = -1;
293
294 static int hf_docsis_sid_cl_sf_id = -1;
295 static int hf_docsis_sid_cl_enc = -1;
296 static int hf_docsis_sid_cl_so_crit = -1;
297
298 static int hf_docsis_sid_cl_enc_id = -1;
299 static int hf_docsis_sid_cl_enc_map = -1;
300
301 static int hf_docsis_sid_cl_map_us_ch_id = -1;
302 static int hf_docsis_sid_cl_map_sid = -1;
303 static int hf_docsis_sid_cl_map_action = -1;
304
305 static int hf_docsis_sid_cl_so_max_req = -1;
306 static int hf_docsis_sid_cl_so_max_out_bytes = -1;
307 static int hf_docsis_sid_cl_so_max_req_bytes = -1;
308 static int hf_docsis_sid_cl_so_max_time = -1;
309
310 static int hf_docsis_tlv_rcp_id = -1;
311 static int hf_docsis_tlv_rcp_name = -1;
312 static int hf_docsis_tlv_rcp_freq_spc = -1;
313 static int hf_docsis_tlv_rcp_rcv_mod_enc = -1;
314 static int hf_docsis_tlv_rcp_rcv_ch = -1;
315 static int hf_docsis_tlv_rcp_ven_spec = -1;
316
317 static int hf_docsis_rcv_mod_enc_idx = -1;
318 static int hf_docsis_rcv_mod_enc_adj_ch = -1;
319 static int hf_docsis_rcv_mod_enc_ch_bl_rng = -1;
320 static int hf_docsis_rcv_mod_enc_ctr_freq_asgn = -1;
321 static int hf_docsis_rcv_mod_enc_rsq_ch_subs_cap = -1;
322 static int hf_docsis_rcv_mod_enc_conn = -1;
323 static int hf_docsis_rcv_mod_enc_phy_layr_parms = -1;
324
325 static int hf_docsis_rcc_rcv_mod_enc_idx = -1;
326 static int hf_docsis_rcc_rcv_mod_enc_ctr_freq_asgn = -1;
327 static int hf_docsis_rcc_rcv_mod_enc_conn = -1;
328
329 static int hf_docsis_ch_bl_rng_min_ctr_freq = -1;
330 static int hf_docsis_ch_bl_rng_max_ctr_freq = -1;
331
332 static int hf_docsis_rcv_ch_idx = -1;
333 static int hf_docsis_rcv_ch_conn = -1;
334 static int hf_docsis_rcv_ch_conn_off = -1;
335 static int hf_docsis_rcv_ch_prim_ds_ch_ind = -1;
336
337 static int hf_docsis_rcc_rcv_ch_idx = -1;
338 static int hf_docsis_rcc_rcv_ch_conn = -1;
339 static int hf_docsis_rcc_rcv_ch_ctr_freq_asgn = -1;
340 static int hf_docsis_rcc_rcv_ch_prim_ds_ch_ind = -1;
341
342 static int hf_docsis_tlv_rcc_id = -1;
343 static int hf_docsis_tlv_rcc_rcv_mod_enc = -1;
344 static int hf_docsis_tlv_rcc_rcv_ch = -1;
345 static int hf_docsis_tlv_rcc_part_serv_ds_ch = -1;
346 static int hf_docsis_tlv_rcc_ven_spec = -1;
347 static int hf_docsis_tlv_rcc_err = -1;
348
349 static int hf_docsis_tlv_rcc_err_mod_or_ch = -1;
350 static int hf_docsis_tlv_rcc_err_idx = -1;
351 static int hf_docsis_tlv_rcc_err_param = -1;
352 static int hf_docsis_tlv_rcc_err_code = -1;
353 static int hf_docsis_tlv_rcc_err_msg = -1;
354
355 static int hf_docsis_tlv_dsid_id = -1;
356 static int hf_docsis_tlv_dsid_action = -1;
357 static int hf_docsis_tlv_dsid_ds_reseq = -1;
358 static int hf_docsis_tlv_dsid_mc = -1;
359
360 static int hf_docsis_ds_reseq_dsid = -1;
361 static int hf_docsis_ds_reseq_ch_lst = -1;
362 static int hf_docsis_ds_reseq_wait_time = -1;
363 static int hf_docsis_ds_reseq_warn_thresh = -1;
364 static int hf_docsis_ds_reseq_ho_timer = -1;
365
366 static int hf_docsis_tlv_dsid_mc_addr = -1;
367 static int hf_docsis_tlv_dsid_mc_cmim = -1;
368 static int hf_docsis_tlv_dsid_mc_group = -1;
369 static int hf_docsis_tlv_dsid_mc_phs = -1;
370
371 static int hf_docsis_mc_addr_action = -1;
372 static int hf_docsis_mc_addr_addr = -1;
373
374 static int hf_docsis_tlv_sec_assoc_action = -1;
375 static int hf_docsis_tlv_sec_assoc_desc = -1;
376
377 static int hf_docsis_ch_asgn_us_ch_id = -1;
378 static int hf_docsis_ch_asgn_rx_freq = -1;
379
380 static int hf_docsis_cmts_mc_sess_enc_grp = -1;
381 static int hf_docsis_cmts_mc_sess_enc_src = -1;
382
383 /* Initialize the subtree pointers */
384 static gint ett_docsis_tlv = -1;
385 static gint ett_docsis_tlv_cos = -1;
386 static gint ett_docsis_tlv_mcap = -1;
387 static gint ett_docsis_tlv_clsfr = -1;
388 static gint ett_docsis_tlv_clsfr_ip = -1;
389 static gint ett_docsis_tlv_clsfr_eth = -1;
390 static gint ett_docsis_tlv_clsfr_err = -1;
391 static gint ett_docsis_tlv_phs = -1;
392 static gint ett_docsis_tlv_phs_err = -1;
393 static gint ett_docsis_tlv_clsfr_dot1q = -1;
394 static gint ett_docsis_tlv_reqxmitpol = -1;
395 static gint ett_docsis_tlv_sflow_err = -1;
396 static gint ett_docsis_tlv_svc_unavail = -1;
397 static gint ett_docsis_tlv_snmpv3_kick = -1;
398 static gint ett_docsis_tlv_ds_ch_list = -1;
399 static gint ett_docsis_tlv_ds_ch_list_single = -1;
400 static gint ett_docsis_tlv_ds_ch_list_range = -1;
401 static gint ett_docsis_tlv_dut_filter = -1;
402 static gint ett_docsis_tlv_tcc = -1;
403 static gint ett_docsis_tlv_tcc_ucd = -1;
404 static gint ett_docsis_tlv_tcc_rng_parms = -1;
405 static gint ett_docsis_tlv_tcc_err = -1;
406 static gint ett_docsis_tlv_sid_cl = -1;
407 static gint ett_docsis_tlv_sid_cl_enc = -1;
408 static gint ett_docsis_tlv_sid_cl_enc_map = -1;
409 static gint ett_docsis_tlv_sid_cl_so = -1;
410 static gint ett_docsis_tlv_rcp = -1;
411 static gint ett_docsis_tlv_rcp_rcv_mod_enc = -1;
412 static gint ett_docsis_tlv_rcp_ch_bl_rng = -1;
413 static gint ett_docsis_tlv_rcp_rcv_ch = -1;
414 static gint ett_docsis_tlv_rcc = -1;
415 static gint ett_docsis_tlv_rcc_rcv_mod_enc = -1;
416 static gint ett_docsis_tlv_rcc_rcv_ch = -1;
417 static gint ett_docsis_tlv_rcc_err = -1;
418 static gint ett_docsis_tlv_dsid = -1;
419 static gint ett_docsis_tlv_dsid_ds_reseq = -1;
420 static gint ett_docsis_tlv_dsid_mc = -1;
421 static gint ett_docsis_tlv_dsid_mc_addr = -1;
422 static gint ett_docsis_tlv_sec_assoc = -1;
423 static gint ett_docsis_tlv_ch_asgn = -1;
424 static gint ett_docsis_cmts_mc_sess_enc = -1;
425
426 static const true_false_string on_off_tfs = {
427   "On",
428   "Off"
429 };
430
431 static const value_string on_off_vals[] = {
432   {0, "Off"},
433   {1, "On"},
434   {0, NULL},
435 };
436
437 static const true_false_string ena_dis_tfs = {
438   "Enable",
439   "Disable"
440 };
441
442 static const value_string docs_ver_vals[] = {
443   {0, "v1.0"},
444   {1, "v1.1"},
445   {0, NULL},
446 };
447
448 static const true_false_string activation_tfs = {
449   "Active",
450   "Inactive"
451 };
452
453 static const value_string dsc_act_vals[] = {
454   {0, "DSC Add Classifier"},
455   {1, "DSC Replace Classifier"},
456   {2, "DSC Delete Classifier"},
457   {0, NULL},
458 };
459
460 static const value_string qos_param_vals[] = {
461   {0x01, "Apply to provisioned set only"},
462   {0x02, "Perform admission control add apply to admitted set"},
463   {0x03, "Apply to provisioned and admitted set; Perform admission control"},
464   {0x04, "Perform admission control if needed and apply to active set"},
465   {0x05,
466    "Apply to provisioned and active sets; Admission control on admitted set in separate service flow, and activate service flow"},
467   {0x06,
468    "Perform admission control and activate; Apply to admitted and active sets"},
469   {0x07,
470    "Apply to Provisioned, Active and Admitted Sets; Admission Control and Activate Service Flow"},
471   {0, NULL},
472 };
473
474 static const value_string sched_type_vals[] = {
475   {0, "Reserved"},
476   {1, "Undefined (CMTS Dependent)"},
477   {2, "Best Effort Service"},
478   {3, "Non-Real-Time Polling Service"},
479   {4, "Real-Time Polling Service"},
480   {5, "Unsolicited Grant Service w/Activity Detection"},
481   {6, "Unsolicited Grant Service"},
482   {0, NULL},
483 };
484
485 static const value_string action_vals[] = {
486   {0, "Add PHS Rule"},
487   {1, "Set PHS Rule"},
488   {2, "Delete PHS Rule"},
489   {3, "Delete all PHS Rules"},
490   {0, NULL},
491 };
492
493 static const true_false_string verify_tfs = {
494   "Don't Verify",
495   "Verify"
496 };
497
498 static const value_string rng_tech_vals[] = {
499   {0, "Perform initial maintenance on new channel"},
500   {1, "Perform only station maintenance on new channel"},
501   {2, "Perform either initial maintenance or station maintenance on new channel"},
502   {3, "Use the new channel directly without performing initial or station maintenance"},
503   {0, NULL},
504 };
505
506
507 const value_string docsis_conf_code[] = {
508   {0, "okay/success"},
509   {1, "Reject: Other/Auth failure (1.0)"},
510   {2, "Reject: Unrecognized configuration setting/COS failure (1.0)"},
511   {3, "Reject: Temporary/Reject resource"},
512   {4, "Reject: Permanent/Reject admin"},
513   {5, "Reject: Not owner"},
514   {6, "Reject: Service flow not found"},
515   {7, "Reject: Service flow exists"},
516   {8, "Reject: Required parameter not present"},
517   {9, "Reject: Header suppression"},
518   {10, "Reject: Unknown transaction id"},
519   {11, "Reject: Authentication failure"},
520   {12, "Reject: Add aborted"},
521   {13, "Reject: Multiple errors"},
522   {14, "Reject: Classifier not found"},
523   {15, "Reject: Classifier exists"},
524   {16, "Reject: PHS rule not found"},
525   {17, "Reject: PHS rule exists"},
526   {18, "Reject: Duplicate reference ID or index in message"},
527   {19, "Reject: Multiple upstream service flows"},
528   {20, "Reject: Multiple downstream service flows"},
529   {21, "Reject: Classifier for another service flow "},
530   {22, "Reject: PHS for another service flow "},
531   {23, "Reject: Parameter invalid for context"},
532   {24, "Reject: Authorization failure"},
533   {25, "Reject: Temporary DCC"},
534   {180, "Depart"},
535   {181, "Arrive"},
536   {182, "Reject: Already There"},
537   {200, "Reject: Major Service Flow Error"},
538   {201, "Reject: Major Classifier Error"},
539   {202, "Reject: Major PHS Rule Error"},
540   {203, "Reject: Multiple Major Errors"},
541   {204, "Reject: Message Syntax Error"},
542   {205, "Reject: Primary Service Flow Error"},
543   {206, "Reject: Message Too Big"},
544   {207, "Reject: Invalid Modem Capabilities"},
545   {0, NULL}
546 };
547
548 static const value_string us_ch_action_vals[] = {
549   {0, "No Action"},
550   {1, "Add"},
551   {2, "Change"},
552   {3, "Delete"},
553   {4, "Replace"},
554   {5, "Re-range"},
555   {0, NULL},
556 };
557
558 static const value_string init_tech_vals[] = {
559   {0, "reserved"},
560   {1, "Perform broadcast initial ranging before normal ops"},
561   {2, "Perform unicast ranging before normal ops"},
562   {3, "Perform either broadcast or unicast ranging before normal ops"},
563   {4, "Use new channel directly without reinitializing or ranging"},
564   {0, NULL},
565 };
566
567 static const value_string sid_ch_map_vals[] = {
568   {0, "reserved"},
569   {1, "Add"},
570   {2, "Delete"},
571   {0, NULL},
572 };
573
574 static const value_string mod_or_ch_vals[] = {
575   {0, "reserved"},
576   {1, "reserved"},
577   {2, "reserved"},
578   {3, "reserved"},
579   {4, "Receive Module"},
580   {5, "Receive Channel"},
581   {0, NULL},
582 };
583
584 static const value_string dsid_action_vals[] = {
585   {0, "Add"},
586   {1, "Change"},
587   {2, "Delete"},
588   {0, NULL},
589 };
590
591 static const value_string add_del_vals[] = {
592   {0, "Add"},
593   {1, "Delete"},
594   {0, NULL},
595 };
596
597 static const value_string init_reason_vals[] = {
598   {0, "reserved"},
599   {1, "Power On"},
600   {2, "T17 Lost Sync"},
601   {3, "All Upstream Failed"},
602   {4, "Bad DHCP Ack"},
603   {5, "Link Local Address in use"},
604   {6, "T6 Expired"},
605   {7, "REG-RSP not ok"},
606   {8, "BAD RCC/TCC"},
607   {9, "Failed Primary Downstream"},
608   {10, "TCS failed on all upstreams"},
609   {11, "reserved"},
610   {12, "reserved"},
611   {13, "reserved"},
612   {14, "reserved"},
613   {15, "MTCM Change"},
614   {16, "T4 Expired"},
615   {17, "No Primary SF on US Channel"},
616   {18, "CM Control Init"},
617   {19, "Dynamic Range Window Violation"},
618   {0, NULL},
619 };
620
621 static const value_string docsis_freq_rng_vals[] = {
622   {0, "Standard Upstream Frequency Range"},
623   {1, "Standard and Extended Upstream Frequency Range"},
624   {0, NULL},
625 };
626
627 static const value_string mc_dsid_fwd_vals[] = {
628   {0, "Support for GMAC explicit multicast DCID Forwarding"},
629   {1, "Support for GMAC promiscuous multicast DCID Forwarding"},
630   {0, NULL},
631 };
632
633 static const value_string fctype_fwd_vals[] = {
634   {0, "Isolation Packet PDU Header (FC_Type of 10) is not forwarded"},
635   {1, "Isolation Packet PDU Header (FC_Type of 10) is forwarded"},
636   {0, NULL},
637 };
638
639 /* Code to actually dissect the packets */
640 static void
641 dissect_phs_err (tvbuff_t * tvb, proto_tree * tree, int start,
642                  guint16 len)
643 {
644   guint8 type, length;
645   proto_item *it;
646   proto_tree *err_tree;
647   int pos = start;
648   it =
649     proto_tree_add_text (tree, tvb, start, len,
650                          "5 Service Flow Error Encodings (Length = %u)", len);
651   err_tree = proto_item_add_subtree (it, ett_docsis_tlv_sflow_err);
652
653   while (pos < (start + len))
654     {
655       type = tvb_get_guint8 (tvb, pos++);
656       length = tvb_get_guint8 (tvb, pos++);
657       switch (type)
658         {
659         case PHS_ERR_PARAM:
660           if (length == 1)
661             {
662               proto_tree_add_item (err_tree, hf_docsis_tlv_phs_err_param, tvb,
663                                    pos, length, ENC_BIG_ENDIAN);
664             }
665           else
666             {
667               THROW (ReportedBoundsError);
668             }
669           break;
670         case PHS_ERR_CODE:
671           if (length == 1)
672             {
673               proto_tree_add_item (err_tree, hf_docsis_tlv_phs_err_code, tvb,
674                                    pos, length, ENC_BIG_ENDIAN);
675             }
676           else
677             {
678               THROW (ReportedBoundsError);
679             }
680           break;
681         case PHS_ERR_MSG:
682           proto_tree_add_item (err_tree, hf_docsis_tlv_phs_err_msg, tvb, pos,
683                                length, ENC_ASCII|ENC_NA);
684           break;
685         }                       /* switch */
686       pos = pos + length;
687
688     }                           /* while */
689 }
690
691 static void
692 dissect_phs (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
693 {
694   guint8 type, length;
695   proto_item *it;
696   proto_tree *phs_tree;
697   int pos = start;
698   it =
699     proto_tree_add_text (tree, tvb, start, len,
700                          "26 PHS Encodings (Length = %u)", len);
701   phs_tree = proto_item_add_subtree (it, ett_docsis_tlv_phs);
702
703   while (pos < (start + len))
704     {
705       type = tvb_get_guint8 (tvb, pos++);
706       length = tvb_get_guint8 (tvb, pos++);
707       switch (type)
708         {
709         case PHS_CLSFR_REF:
710           if (length == 1)
711             {
712               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_class_ref, tvb,
713                                    pos, length, ENC_BIG_ENDIAN);
714             }
715           else
716             {
717               THROW (ReportedBoundsError);
718             }
719           break;
720         case PHS_CLSFR_ID:
721           if (length == 2)
722             {
723               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_class_id, tvb,
724                                    pos, length, ENC_BIG_ENDIAN);
725             }
726           else
727             {
728               THROW (ReportedBoundsError);
729             }
730           break;
731         case PHS_SFLOW_REF:
732           if (length == 2)
733             {
734               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_sflow_ref, tvb,
735                                    pos, length, ENC_BIG_ENDIAN);
736             }
737           else
738             {
739               THROW (ReportedBoundsError);
740             }
741           break;
742         case PHS_SFLOW_ID:
743           if (length == 4)
744             {
745               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_sflow_id, tvb,
746                                    pos, length, ENC_BIG_ENDIAN);
747             }
748           else
749             {
750               THROW (ReportedBoundsError);
751             }
752           break;
753         case PHS_DSC_ACTION:
754           if (length == 1)
755             {
756               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_dsc_action,
757                                    tvb, pos, length, ENC_BIG_ENDIAN);
758             }
759           else
760             {
761               THROW (ReportedBoundsError);
762             }
763           break;
764         case PHS_ERRORS:
765           dissect_phs_err (tvb, phs_tree, pos, length);
766         case PHS_FIELD:
767           proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phsf, tvb, pos,
768                                length, ENC_NA);
769           break;
770         case PHS_INDEX:
771           if (length == 1)
772             {
773               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phsi, tvb, pos,
774                                    length, ENC_BIG_ENDIAN);
775             }
776           else
777             {
778               THROW (ReportedBoundsError);
779             }
780           break;
781         case PHS_MASK:
782           proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phsm, tvb, pos,
783                                length, ENC_NA);
784           break;
785         case PHS_SUP_SIZE:
786           if (length == 1)
787             {
788               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phss, tvb, pos,
789                                    length, ENC_BIG_ENDIAN);
790             }
791           else
792             {
793               THROW (ReportedBoundsError);
794             }
795           break;
796         case PHS_VERIFICATION:
797           if (length == 1)
798             {
799               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phsf, tvb, pos,
800                                    length, ENC_NA);
801             }
802           else
803             {
804               THROW (ReportedBoundsError);
805             }
806           break;
807         case PHS_VENDOR_SPEC:
808           proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_vendorspec, tvb,
809                                pos, length, ENC_NA);
810           break;
811         }                       /* switch */
812       pos = pos + length;
813
814     }                           /* while */
815 }
816
817
818 static void
819 dissect_reqxmit_policy (tvbuff_t * tvb, proto_tree * tree, int start)
820 {
821   guint32 value;
822   proto_item *it;
823   proto_tree *pol_tree;
824
825   value = tvb_get_ntohl (tvb, start);
826   it =
827     proto_tree_add_item (tree, hf_docsis_tlv_sflow_reqxmit_pol, tvb, start, 4,
828                          ENC_BIG_ENDIAN);
829   pol_tree = proto_item_add_subtree (it, ett_docsis_tlv_reqxmitpol);
830
831   if (value & 0x01)
832     proto_tree_add_text (pol_tree, tvb, start, 4,
833                          "Service flow MUST NOT use \"all CMs\" broadcast request opportunities");
834   if (value & 0x02)
835     proto_tree_add_text (pol_tree, tvb, start, 4,
836                          "Service flow MUST NOT use priority multicast request opportunities");
837   if (value & 0x04)
838     proto_tree_add_text (pol_tree, tvb, start, 4,
839                          "Service flow MUST NOT use Request/Data opportunities for requests");
840   if (value & 0x08)
841     proto_tree_add_text (pol_tree, tvb, start, 4,
842                          "Service flow MUST NOT use Request/Data opportunities for data");
843   if (value & 0x10)
844     proto_tree_add_text (pol_tree, tvb, start, 4,
845                          "Service flow MUST NOT use piggy back requests with data");
846   if (value & 0x20)
847     proto_tree_add_text (pol_tree, tvb, start, 4,
848                          "Service flow MUST NOT concatenate data");
849   if (value & 0x40)
850     proto_tree_add_text (pol_tree, tvb, start, 4,
851                          "Service flow MUST NOT fragment data");
852   if (value & 0x80)
853     proto_tree_add_text (pol_tree, tvb, start, 4,
854                          "Service flow MUST NOT suppress payload headers");
855   if (value & 0x100)
856     proto_tree_add_text (pol_tree, tvb, start, 4,
857                          "Service flow MUST drop packets that do not fit in the UGS size");
858 }
859
860 static void
861 dissect_sflow_err (tvbuff_t * tvb, proto_tree * tree, int start,
862                    guint16 len)
863 {
864   guint8 type, length;
865   proto_item *it;
866   proto_tree *err_tree;
867   int pos = start;
868   it =
869     proto_tree_add_text (tree, tvb, start, len,
870                          "5 Service Flow Error Encodings (Length = %u)", len);
871   err_tree = proto_item_add_subtree (it, ett_docsis_tlv_sflow_err);
872
873   while (pos < (start + len))
874     {
875       type = tvb_get_guint8 (tvb, pos++);
876       length = tvb_get_guint8 (tvb, pos++);
877       switch (type)
878         {
879         case SFW_ERR_PARAM:
880           if (length == 1)
881             {
882               proto_tree_add_item (err_tree, hf_docsis_tlv_sflow_err_param,
883                                    tvb, pos, length, ENC_BIG_ENDIAN);
884             }
885           else
886             {
887               THROW (ReportedBoundsError);
888             }
889           break;
890         case SFW_ERR_CODE:
891           if (length == 1)
892             {
893               proto_tree_add_item (err_tree, hf_docsis_tlv_sflow_err_code,
894                                    tvb, pos, length, ENC_BIG_ENDIAN);
895             }
896           else
897             {
898               THROW (ReportedBoundsError);
899             }
900           break;
901         case SFW_ERR_MSG:
902           proto_tree_add_item (err_tree, hf_docsis_tlv_sflow_err_msg, tvb,
903                                pos, length, ENC_ASCII|ENC_NA);
904           break;
905         }                       /* switch */
906       pos = pos + length;
907
908     }                           /* while */
909 }
910
911 static void
912 dissect_downstream_sflow (tvbuff_t * tvb, proto_tree * sflow_tree,
913                           int start, guint16 len)
914 {
915   guint8 type, length;
916   int pos = start;
917   while (pos < (start + len))
918     {
919       type = tvb_get_guint8 (tvb, pos++);
920       length = tvb_get_guint8 (tvb, pos++);
921       switch (type)
922         {
923         case SFW_MAX_DOWN_LAT:
924           if (length == 4)
925             {
926               proto_tree_add_item (sflow_tree,
927                                    hf_docsis_tlv_sflow_max_down_latency, tvb,
928                                    pos, length, ENC_BIG_ENDIAN);
929             }
930           else
931             {
932               THROW (ReportedBoundsError);
933
934             }
935           break;
936         }                       /* switch */
937       pos = pos + length;
938
939     }                           /* while */
940 }
941
942 static void
943 dissect_upstream_sflow (tvbuff_t * tvb, proto_tree * sflow_tree,
944                         int start, guint16 len)
945 {
946   guint8 type, length;
947   int pos = start;
948   while (pos < (start + len))
949     {
950       type = tvb_get_guint8 (tvb, pos++);
951       length = tvb_get_guint8 (tvb, pos++);
952       switch (type)
953         {
954         case SFW_MAX_CONCAT_BURST:
955           if (length == 2)
956             {
957               proto_tree_add_item (sflow_tree,
958                                    hf_docsis_tlv_sflow_max_concat_burst, tvb,
959                                    pos, length, ENC_BIG_ENDIAN);
960             }
961           else
962             {
963               THROW (ReportedBoundsError);
964
965             }
966           break;
967         case SFW_SCHEDULING_TYPE:
968           if (length == 1)
969             {
970               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_sched_type,
971                                    tvb, pos, length, ENC_BIG_ENDIAN);
972             }
973           else
974             {
975               THROW (ReportedBoundsError);
976             }
977           break;
978         case SFW_REQ_XMIT_POL:
979           dissect_reqxmit_policy (tvb, sflow_tree, pos);
980           break;
981         case SFW_NOM_POLL_INT:
982           if (length == 4)
983             {
984               proto_tree_add_item (sflow_tree,
985                                    hf_docsis_tlv_sflow_nominal_polling, tvb,
986                                    pos, length, ENC_BIG_ENDIAN);
987             }
988           else
989             {
990               THROW (ReportedBoundsError);
991             }
992           break;
993         case SFW_POLL_JTTR_TOL:
994           if (length == 4)
995             {
996               proto_tree_add_item (sflow_tree,
997                                    hf_docsis_tlv_sflow_tolerated_jitter, tvb,
998                                    pos, length, ENC_BIG_ENDIAN);
999             }
1000           else
1001             {
1002               THROW (ReportedBoundsError);
1003             }
1004           break;
1005         case SFW_UG_SIZE:
1006           if (length == 2)
1007             {
1008               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_ugs_size,
1009                                    tvb, pos, length, ENC_BIG_ENDIAN);
1010             }
1011           else
1012             {
1013               THROW (ReportedBoundsError);
1014             }
1015           break;
1016         case SFW_NOM_GRNT_INTV:
1017           if (length == 4)
1018             {
1019               proto_tree_add_item (sflow_tree,
1020                                    hf_docsis_tlv_sflow_nom_grant_intvl, tvb,
1021                                    pos, length, ENC_BIG_ENDIAN);
1022             }
1023           else
1024             {
1025               THROW (ReportedBoundsError);
1026             }
1027           break;
1028         case SFW_GRNT_JTTR_TOL:
1029           if (length == 4)
1030             {
1031               proto_tree_add_item (sflow_tree,
1032                                    hf_docsis_tlv_sflow_tol_grant_jitter, tvb,
1033                                    pos, length, ENC_BIG_ENDIAN);
1034             }
1035           else
1036             {
1037               THROW (ReportedBoundsError);
1038             }
1039           break;
1040         case SFW_GRNTS_PER_INTV:
1041           if (length == 1)
1042             {
1043               proto_tree_add_item (sflow_tree,
1044                                    hf_docsis_tlv_sflow_grants_per_intvl, tvb,
1045                                    pos, length, ENC_BIG_ENDIAN);
1046             }
1047           else
1048             {
1049               THROW (ReportedBoundsError);
1050             }
1051           break;
1052         case SFW_IP_TOS_OVERWRITE:
1053           if (length == 2)
1054             {
1055               proto_tree_add_item (sflow_tree,
1056                                    hf_docsis_tlv_sflow_ip_tos_overwrite, tvb,
1057                                    pos, length, ENC_BIG_ENDIAN);
1058             }
1059           else
1060             {
1061               THROW (ReportedBoundsError);
1062             }
1063           break;
1064         case SFW_UG_TIME_REF:
1065           if (length == 4)
1066             {
1067               proto_tree_add_item (sflow_tree,
1068                                    hf_docsis_tlv_sflow_ugs_timeref, tvb, pos,
1069                                    length, ENC_BIG_ENDIAN);
1070             }
1071           else
1072             {
1073               THROW (ReportedBoundsError);
1074             }
1075           break;
1076
1077         }                       /* switch */
1078       pos = pos + length;
1079
1080     }                           /* while */
1081 }
1082
1083 static void
1084 dissect_sflow (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len,
1085                guint8 direction)
1086 {
1087   guint8 type, length;
1088   proto_item *it;
1089   proto_tree *sflow_tree;
1090   int pos = start;
1091   if (direction == 24)
1092     it =
1093       proto_tree_add_text (tree, tvb, start, len,
1094                            "24 Upstream Service Flow (Length = %u)", len);
1095   else if (direction == 25)
1096     it =
1097       proto_tree_add_text (tree, tvb, start, len,
1098                            "25 Downstream Service Flow (Length = %u)", len);
1099   else
1100     return;
1101   sflow_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr);
1102
1103   while (pos < (start + len))
1104     {
1105       type = tvb_get_guint8 (tvb, pos++);
1106       length = tvb_get_guint8 (tvb, pos++);
1107       switch (type)
1108         {
1109         case SFW_REF:
1110           if (length == 2)
1111             {
1112               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_ref, tvb,
1113                                    pos, length, ENC_BIG_ENDIAN);
1114             }
1115           else
1116             {
1117               THROW (ReportedBoundsError);
1118             }
1119           break;
1120         case SFW_ID:
1121           if (length == 4)
1122             {
1123               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_id, tvb,
1124                                    pos, length, ENC_BIG_ENDIAN);
1125             }
1126           else
1127             {
1128               THROW (ReportedBoundsError);
1129             }
1130           break;
1131         case SFW_SID:
1132           if (length == 2)
1133             {
1134               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_sid, tvb,
1135                                    pos, length, ENC_BIG_ENDIAN);
1136             }
1137           else
1138             {
1139               THROW (ReportedBoundsError);
1140             }
1141           break;
1142         case SFW_SERVICE_CLASS_NAME:
1143           proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_classname, tvb,
1144                                pos, length, ENC_ASCII|ENC_NA);
1145           break;
1146         case SFW_ERRORS:
1147           dissect_sflow_err (tvb, sflow_tree, pos, length);
1148           break;
1149         case SFW_QOS_SET_TYPE:
1150           if (length == 1)
1151             {
1152               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_qos_param,
1153                                    tvb, pos, length, ENC_BIG_ENDIAN);
1154             }
1155           else
1156             {
1157               THROW (ReportedBoundsError);
1158             }
1159           break;
1160         case SFW_TRAF_PRI:
1161           if (length == 1)
1162             {
1163               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_traf_pri,
1164                                    tvb, pos, length, ENC_BIG_ENDIAN);
1165             }
1166           else
1167             {
1168               THROW (ReportedBoundsError);
1169             }
1170           break;
1171         case SFW_MAX_SUSTAINED:
1172           if (length == 4)
1173             {
1174               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_max_sus,
1175                                    tvb, pos, length, ENC_BIG_ENDIAN);
1176             }
1177           else
1178             {
1179               THROW (ReportedBoundsError);
1180             }
1181           break;
1182         case SFW_MAX_BURST:
1183           if (length == 4)
1184             {
1185               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_max_burst,
1186                                    tvb, pos, length, ENC_BIG_ENDIAN);
1187             }
1188           else
1189             {
1190               THROW (ReportedBoundsError);
1191             }
1192           break;
1193         case SFW_MIN_RSVD_TRAF:
1194           if (length == 4)
1195             {
1196               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_min_traf,
1197                                    tvb, pos, length, ENC_BIG_ENDIAN);
1198             }
1199           else
1200             {
1201               THROW (ReportedBoundsError);
1202             }
1203           break;
1204         case SFW_MIN_RSVD_PACKETSIZE:
1205           if (length == 2)
1206             {
1207               proto_tree_add_item (sflow_tree,
1208                                    hf_docsis_tlv_sflow_ass_min_pkt_size, tvb,
1209                                    pos, length, ENC_BIG_ENDIAN);
1210             }
1211           else
1212             {
1213               THROW (ReportedBoundsError);
1214             }
1215           break;
1216         case SFW_ACTIVE_QOS_TIMEOUT:
1217           if (length == 2)
1218             {
1219               proto_tree_add_item (sflow_tree,
1220                                    hf_docsis_tlv_sflow_timeout_active, tvb,
1221                                    pos, length, ENC_BIG_ENDIAN);
1222             }
1223           else
1224             {
1225               THROW (ReportedBoundsError);
1226             }
1227           break;
1228         case SFW_ADMITT_QOS_TIMEOUT:
1229           if (length == 2)
1230             {
1231               proto_tree_add_item (sflow_tree,
1232                                    hf_docsis_tlv_sflow_timeout_admitted, tvb,
1233                                    pos, length, ENC_BIG_ENDIAN);
1234             }
1235           else
1236             {
1237               THROW (ReportedBoundsError);
1238             }
1239           break;
1240         case SFW_VENDOR_SPEC:
1241           proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_vendor_spec,
1242                                tvb, pos, length, ENC_NA);
1243           break;
1244         default:
1245           if (direction == 24)
1246             dissect_upstream_sflow (tvb, sflow_tree, pos - 2, length);
1247           else
1248             dissect_downstream_sflow (tvb, sflow_tree, pos - 2, length);
1249           break;
1250
1251         }                       /* switch (type) */
1252       pos = pos + length;
1253     }                           /* while(pos < start + len) */
1254
1255 }
1256
1257 static void
1258 dissect_dot1q_clsfr (tvbuff_t * tvb, proto_tree * tree, int start,
1259                      guint16 len)
1260 {
1261   guint8 type, length;
1262   proto_item *it;
1263   proto_tree *dot1qclsfr_tree;
1264   int pos = start;
1265   it =
1266     proto_tree_add_text (tree, tvb, start, len,
1267                          "11 801.1P/Q Classifiers (Length = %u)", len);
1268   dot1qclsfr_tree = proto_item_add_subtree (it, ett_docsis_tlv_cos);
1269
1270   while (pos < (start + len))
1271     {
1272       type = tvb_get_guint8 (tvb, pos++);
1273       length = tvb_get_guint8 (tvb, pos++);
1274       switch (type)
1275         {
1276         case CFR_D1Q_USER_PRI:
1277           if (length == 2)
1278             {
1279               proto_tree_add_item (dot1qclsfr_tree,
1280                                    hf_docsis_tlv_dot1qclsfr_user_pri, tvb,
1281                                    pos, length, ENC_BIG_ENDIAN);
1282             }
1283           else
1284             {
1285               THROW (ReportedBoundsError);
1286             }
1287           break;
1288         case CFR_D1Q_VLAN_ID:
1289           if (length == 2)
1290             {
1291               proto_tree_add_item (dot1qclsfr_tree,
1292                                    hf_docsis_tlv_dot1qclsfr_vlanid, tvb, pos,
1293                                    length, ENC_BIG_ENDIAN);
1294             }
1295           else
1296             {
1297               THROW (ReportedBoundsError);
1298             }
1299           break;
1300         case CFR_D1Q_VENDOR_SPEC:
1301           proto_tree_add_item (dot1qclsfr_tree,
1302                                hf_docsis_tlv_dot1qclsfr_vendorspec, tvb, pos,
1303                                length, ENC_NA);
1304           break;
1305         }                       /* switch */
1306       pos = pos + length;
1307
1308     }                           /* while */
1309 }
1310
1311 static void
1312 dissect_eth_clsfr (tvbuff_t * tvb, proto_tree * tree, int start,
1313                    guint16 len)
1314 {
1315   guint8 type, length;
1316   proto_item *it;
1317   proto_tree *ethclsfr_tree;
1318   int pos = start;
1319   it =
1320     proto_tree_add_text (tree, tvb, start, len,
1321                          "10 Ethernet Classifiers (Length = %u)", len);
1322   ethclsfr_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr_eth);
1323
1324   while (pos < (start + len))
1325     {
1326       type = tvb_get_guint8 (tvb, pos++);
1327       length = tvb_get_guint8 (tvb, pos++);
1328       switch (type)
1329         {
1330         case CFR_ETH_DST_MAC:
1331           if (length == 6)
1332             {
1333               proto_tree_add_item (ethclsfr_tree, hf_docsis_tlv_ethclsfr_dmac,
1334                                    tvb, pos, length, ENC_NA);
1335             }
1336           else
1337             {
1338               THROW (ReportedBoundsError);
1339             }
1340           break;
1341         case CFR_ETH_SRC_MAC:
1342           if (length == 6)
1343             {
1344               proto_tree_add_item (ethclsfr_tree, hf_docsis_tlv_ethclsfr_smac,
1345                                    tvb, pos, length, ENC_NA);
1346             }
1347           else
1348             {
1349               THROW (ReportedBoundsError);
1350             }
1351           break;
1352         case CFR_ETH_DSAP:
1353           if (length == 3)
1354             {
1355               proto_tree_add_item (ethclsfr_tree,
1356                                    hf_docsis_tlv_ethclsfr_ethertype, tvb, pos,
1357                                    length, ENC_BIG_ENDIAN);
1358             }
1359           else
1360             {
1361               THROW (ReportedBoundsError);
1362             }
1363           break;
1364         }                       /* switch */
1365       pos = pos + length;
1366
1367     }                           /* while */
1368
1369
1370
1371 }
1372
1373 static void
1374 dissect_clsfr_err (tvbuff_t * tvb, proto_tree * tree, int start,
1375                    guint16 len)
1376 {
1377   guint8 type, length;
1378   proto_item *it;
1379   proto_tree *err_tree;
1380   int pos = start;
1381   it =
1382     proto_tree_add_text (tree, tvb, start, len,
1383                          "8 Classifier Error Encodings (Length = %u)", len);
1384   err_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr_err);
1385
1386   while (pos < (start + len))
1387     {
1388       type = tvb_get_guint8 (tvb, pos++);
1389       length = tvb_get_guint8 (tvb, pos++);
1390       switch (type)
1391         {
1392         case CFR_ERR_PARAM:
1393           if (length == 1)
1394             proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_param, tvb,
1395                                  pos, length, ENC_BIG_ENDIAN);
1396           else if (length == 2)
1397             {
1398               proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_param,
1399                                    tvb, pos, 1, ENC_BIG_ENDIAN);
1400               proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_param,
1401                                    tvb, pos + 1, 1, ENC_BIG_ENDIAN);
1402             }
1403           else
1404             {
1405               THROW (ReportedBoundsError);
1406             }
1407           break;
1408         case CFR_ERR_CODE:
1409           if (length == 1)
1410             {
1411               proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_code,
1412                                    tvb, pos, length, ENC_BIG_ENDIAN);
1413             }
1414           else
1415             {
1416               THROW (ReportedBoundsError);
1417             }
1418           break;
1419         case CFR_ERR_MSG:
1420           proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_msg, tvb,
1421                                pos, length, ENC_ASCII|ENC_NA);
1422           break;
1423         }                       /* switch */
1424       pos = pos + length;
1425
1426     }                           /* while */
1427
1428
1429
1430 }
1431
1432 static void
1433 dissect_ip_classifier (tvbuff_t * tvb, proto_tree * tree, int start,
1434                        guint16 len)
1435 {
1436   guint8 type, length;
1437   proto_item *it;
1438   proto_tree *ipclsfr_tree;
1439   int pos = start;
1440   it =
1441     proto_tree_add_text (tree, tvb, start, len,
1442                          "9 IP Classifier (Length = %u)", len);
1443   ipclsfr_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr_ip);
1444
1445   while (pos < (start + len))
1446     {
1447       type = tvb_get_guint8 (tvb, pos++);
1448       length = tvb_get_guint8 (tvb, pos++);
1449       switch (type)
1450         {
1451         case CFR_IP_TOS_RANGE_MASK:
1452           if (length == 3)
1453             {
1454               proto_tree_add_item (ipclsfr_tree,
1455                                    hf_docsis_tlv_ipclsfr_tosmask, tvb, pos,
1456                                    length, ENC_NA);
1457             }
1458           else
1459             {
1460               THROW (ReportedBoundsError);
1461             }
1462           break;
1463         case CFR_IP_PROTO:
1464           if (length == 2)
1465             {
1466               proto_tree_add_item (ipclsfr_tree,
1467                                    hf_docsis_tlv_ipclsfr_ipproto, tvb, pos,
1468                                    length, ENC_BIG_ENDIAN);
1469             }
1470           else
1471             {
1472               THROW (ReportedBoundsError);
1473             }
1474           break;
1475         case CFR_IP_SOURCE_ADDR:
1476           if (length == 4)
1477             {
1478               proto_tree_add_item (ipclsfr_tree, hf_docsis_tlv_ipclsfr_src,
1479                                    tvb, pos, length, ENC_BIG_ENDIAN);
1480             }
1481           else
1482             {
1483               THROW (ReportedBoundsError);
1484             }
1485           break;
1486         case CFR_IP_SOURCE_MASK:
1487           if (length == 4)
1488             {
1489               proto_tree_add_item (ipclsfr_tree,
1490                                    hf_docsis_tlv_ipclsfr_srcmask, tvb, pos,
1491                                    length, ENC_BIG_ENDIAN);
1492             }
1493           else
1494             {
1495               THROW (ReportedBoundsError);
1496             }
1497           break;
1498         case CFR_IP_DEST_ADDR:
1499           if (length == 4)
1500             {
1501               proto_tree_add_item (ipclsfr_tree, hf_docsis_tlv_ipclsfr_dst,
1502                                    tvb, pos, length, ENC_BIG_ENDIAN);
1503             }
1504           else
1505             {
1506               THROW (ReportedBoundsError);
1507             }
1508           break;
1509         case CFR_IP_DEST_MASK:
1510           if (length == 4)
1511             {
1512               proto_tree_add_item (ipclsfr_tree,
1513                                    hf_docsis_tlv_ipclsfr_dstmask, tvb, pos,
1514                                    length, ENC_BIG_ENDIAN);
1515             }
1516           else
1517             {
1518               THROW (ReportedBoundsError);
1519             }
1520           break;
1521         case CFR_IP_SRCPORT_START:
1522           if (length == 2)
1523             {
1524               proto_tree_add_item (ipclsfr_tree,
1525                                    hf_docsis_tlv_ipclsfr_sport_start, tvb,
1526                                    pos, length, ENC_BIG_ENDIAN);
1527             }
1528           else
1529             {
1530               THROW (ReportedBoundsError);
1531             }
1532           break;
1533         case CFR_IP_SRCPORT_END:
1534           if (length == 2)
1535             {
1536               proto_tree_add_item (ipclsfr_tree,
1537                                    hf_docsis_tlv_ipclsfr_sport_end, tvb, pos,
1538                                    length, ENC_BIG_ENDIAN);
1539             }
1540           else
1541             {
1542               THROW (ReportedBoundsError);
1543             }
1544           break;
1545         case CFR_IP_DSTPORT_START:
1546           if (length == 2)
1547             {
1548               proto_tree_add_item (ipclsfr_tree,
1549                                    hf_docsis_tlv_ipclsfr_dport_start, tvb,
1550                                    pos, length, ENC_BIG_ENDIAN);
1551             }
1552           else
1553             {
1554               THROW (ReportedBoundsError);
1555             }
1556           break;
1557         case CFR_IP_DSTPORT_END:
1558           if (length == 2)
1559             {
1560               proto_tree_add_item (ipclsfr_tree,
1561                                    hf_docsis_tlv_ipclsfr_dport_end, tvb, pos,
1562                                    length, ENC_BIG_ENDIAN);
1563             }
1564           else
1565             {
1566               THROW (ReportedBoundsError);
1567             }
1568           break;
1569         }                       /* switch */
1570       pos = pos + length;
1571
1572     }                           /* while */
1573
1574 }
1575 static void
1576 dissect_classifiers (tvbuff_t * tvb, proto_tree * tree, int start,
1577                      guint16 len, guint8 direction)
1578 {
1579   guint8 type, length;
1580   proto_item *it;
1581   proto_tree *clsfr_tree;
1582   int pos = start;
1583   if (direction == 22)
1584     it =
1585       proto_tree_add_text (tree, tvb, start, len,
1586                            "22 Upstream Packet Classifier (Length = %u)",
1587                            len);
1588   else if (direction == 23)
1589     it =
1590       proto_tree_add_text (tree, tvb, start, len,
1591                            "23 Downstream Packet Classifier (Length = %u)",
1592                            len);
1593   else
1594     return;
1595   clsfr_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr);
1596
1597   while (pos < (start + len))
1598     {
1599       type = tvb_get_guint8 (tvb, pos++);
1600       length = tvb_get_guint8 (tvb, pos++);
1601       switch (type)
1602         {
1603         case CFR_REF:
1604           if (length == 1)
1605             {
1606               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_ref, tvb,
1607                                    pos, length, ENC_BIG_ENDIAN);
1608             }
1609           else
1610             {
1611               THROW (ReportedBoundsError);
1612             }
1613           break;
1614         case CFR_ID:
1615           if (length == 2)
1616             {
1617               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_id, tvb,
1618                                    pos, length, ENC_BIG_ENDIAN);
1619             }
1620           else
1621             {
1622               THROW (ReportedBoundsError);
1623             }
1624           break;
1625         case CFR_SFLOW_REF:
1626           if (length == 2)
1627             {
1628               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_sflow_ref,
1629                                    tvb, pos, length, ENC_BIG_ENDIAN);
1630             }
1631           else
1632             {
1633               THROW (ReportedBoundsError);
1634             }
1635           break;
1636         case CFR_SFLOW_ID:
1637           if (length == 4)
1638             {
1639               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_sflow_id,
1640                                    tvb, pos, length, ENC_BIG_ENDIAN);
1641             }
1642           else
1643             {
1644               THROW (ReportedBoundsError);
1645             }
1646           break;
1647         case CFR_RULE_PRI:
1648           if (length == 1)
1649             {
1650               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_rule_pri,
1651                                    tvb, pos, length, ENC_BIG_ENDIAN);
1652             }
1653           else
1654             {
1655               THROW (ReportedBoundsError);
1656             }
1657           break;
1658         case CFR_ACT_STATE:
1659           if (length == 1)
1660             {
1661               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_act_state,
1662                                    tvb, pos, length, ENC_BIG_ENDIAN);
1663             }
1664           else
1665             {
1666               THROW (ReportedBoundsError);
1667             }
1668           break;
1669         case CFR_DSA_ACTION:
1670           if (length == 1)
1671             {
1672               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_dsc_act,
1673                                    tvb, pos, length, ENC_BIG_ENDIAN);
1674             }
1675           else
1676             {
1677               THROW (ReportedBoundsError);
1678             }
1679           break;
1680         case CFR_ERROR:
1681           dissect_clsfr_err (tvb, clsfr_tree, pos, length);
1682           break;
1683         case CFR_IP_CLASSIFIER:
1684           dissect_ip_classifier (tvb, clsfr_tree, pos, length);
1685           break;
1686         case CFR_ETH_CLASSIFIER:
1687           dissect_eth_clsfr (tvb, clsfr_tree, pos, length);
1688           break;
1689         case CFR_8021Q_CLASSIFIER:
1690           dissect_dot1q_clsfr (tvb, clsfr_tree, pos, length);
1691           break;
1692         case CFR_VENDOR_SPEC:
1693           proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_vendor_spc,
1694                                tvb, pos, length, ENC_NA);
1695           break;
1696         }                       /* switch */
1697       pos = pos + length;
1698
1699     }                           /* while */
1700
1701
1702
1703 }
1704
1705 static void
1706 dissect_doc10cos (tvbuff_t * tvb, proto_tree * tree, int start,
1707                   guint16 len)
1708 {
1709   guint8 type, length;
1710   proto_item *it;
1711   proto_tree *doc10cos_tree;
1712   int pos = start;
1713   it =
1714     proto_tree_add_text (tree, tvb, start, len,
1715                          "1 Docsis 1.0 Class of Service (Length = %u)", len);
1716   doc10cos_tree = proto_item_add_subtree (it, ett_docsis_tlv_cos);
1717
1718   while (pos < (start + len))
1719     {
1720       type = tvb_get_guint8 (tvb, pos++);
1721       length = tvb_get_guint8 (tvb, pos++);
1722       switch (type)
1723         {
1724         case 1:
1725           if (length == 1)
1726             {
1727               proto_tree_add_item (doc10cos_tree, hf_docsis_tlv_cos_id, tvb,
1728                                    pos, length, ENC_BIG_ENDIAN);
1729             }
1730           else
1731             {
1732               THROW (ReportedBoundsError);
1733             }
1734           break;
1735         case 2:
1736           if (length == 2)
1737             {
1738               proto_tree_add_item (doc10cos_tree, hf_docsis_tlv_cos_sid, tvb,
1739                                    pos, length, ENC_BIG_ENDIAN);
1740             }
1741           else
1742             {
1743               THROW (ReportedBoundsError);
1744             }
1745           break;
1746         }                       /* switch */
1747       pos = pos + length;
1748
1749     }                           /* while */
1750 }
1751
1752 static void
1753 dissect_modemcap (tvbuff_t * tvb, proto_tree * tree, int start,
1754                   guint16 len)
1755 {
1756   guint8 type, length;
1757   proto_item *it;
1758   proto_tree *mcap_tree;
1759   int pos = start;
1760
1761   it =
1762     proto_tree_add_text (tree, tvb, start, len,
1763                          "5 Modem Capabilities Type (Length = %u)", len);
1764
1765   mcap_tree = proto_item_add_subtree (it, ett_docsis_tlv_mcap);
1766   while (pos < (start + len))
1767     {
1768       type = tvb_get_guint8 (tvb, pos++);
1769       length = tvb_get_guint8 (tvb, pos++);
1770       switch (type)
1771         {
1772         case CAP_CONCAT:
1773           if (length == 1)
1774             {
1775               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_concat, tvb,
1776                                    pos, length, ENC_BIG_ENDIAN);
1777             }
1778           else
1779             {
1780               THROW (ReportedBoundsError);
1781             }
1782           break;
1783         case CAP_DOCSIS_VER:
1784           if (length == 1)
1785             {
1786               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_docs_ver,
1787                                    tvb, pos, length, ENC_BIG_ENDIAN);
1788             }
1789           else
1790             {
1791               THROW (ReportedBoundsError);
1792             }
1793           break;
1794         case CAP_FRAG:
1795           if (length == 1)
1796             {
1797               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_frag, tvb,
1798                                    pos, length, ENC_BIG_ENDIAN);
1799             }
1800           else
1801             {
1802               THROW (ReportedBoundsError);
1803             }
1804           break;
1805         case CAP_PHS:
1806           if (length == 1)
1807             {
1808               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_phs, tvb,
1809                                    pos, length, ENC_BIG_ENDIAN);
1810             }
1811           else
1812             {
1813               THROW (ReportedBoundsError);
1814             }
1815           break;
1816         case CAP_IGMP:
1817           if (length == 1)
1818             {
1819               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_igmp, tvb,
1820                                    pos, length, ENC_BIG_ENDIAN);
1821             }
1822           else
1823             {
1824               THROW (ReportedBoundsError);
1825             }
1826           break;
1827         case CAP_PRIVACY:
1828           if (length == 1)
1829             {
1830               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_privacy, tvb,
1831                                    pos, length, ENC_BIG_ENDIAN);
1832             }
1833           else
1834             {
1835               THROW (ReportedBoundsError);
1836             }
1837           break;
1838         case CAP_DOWN_SAID:
1839           if (length == 1)
1840             {
1841               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_down_said,
1842                                    tvb, pos, length, ENC_BIG_ENDIAN);
1843             }
1844           else
1845             {
1846               THROW (ReportedBoundsError);
1847             }
1848           break;
1849         case CAP_UP_SID:
1850           if (length == 1)
1851             {
1852               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_up_sid, tvb,
1853                                    pos, length, ENC_BIG_ENDIAN);
1854             }
1855           else
1856             {
1857               THROW (ReportedBoundsError);
1858             }
1859           break;
1860         case CAP_OPT_FILT:
1861           if (length == 1)
1862             {
1863               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_8021P_filter,
1864                                    tvb, pos, length, ENC_BIG_ENDIAN);
1865               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_8021Q_filter,
1866                                    tvb, pos, length, ENC_BIG_ENDIAN);
1867             }
1868           else
1869             {
1870               THROW (ReportedBoundsError);
1871             }
1872           break;
1873         case CAP_XMIT_EQPERSYM:
1874           if (length == 1)
1875             {
1876               proto_tree_add_item (mcap_tree,
1877                                    hf_docsis_tlv_mcap_xmit_eq_taps_per_sym,
1878                                    tvb, pos, length, ENC_BIG_ENDIAN);
1879             }
1880           else
1881             {
1882               THROW (ReportedBoundsError);
1883             }
1884           break;
1885         case CAP_NUM_XMIT_EQ_TAPS:
1886           if (length == 1)
1887             {
1888               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_xmit_eq_taps,
1889                                    tvb, pos, length, ENC_BIG_ENDIAN);
1890             }
1891           else
1892             {
1893               THROW (ReportedBoundsError);
1894             }
1895           break;
1896         case CAP_DCC:
1897           if (length == 1)
1898             {
1899               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_dcc, tvb,
1900                                    pos, length, ENC_BIG_ENDIAN);
1901             }
1902           else
1903             {
1904               THROW (ReportedBoundsError);
1905             }
1906           break;
1907         case CAP_IP_FILTERS:
1908           if (length == 2)
1909             {
1910               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_ip_filters, tvb,
1911                                    pos, length, ENC_BIG_ENDIAN);
1912             }
1913           else
1914             {
1915               THROW (ReportedBoundsError);
1916             }
1917           break;
1918         case CAP_LLC_FILTERS:
1919           if (length == 2)
1920             {
1921               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_llc_filters, tvb,
1922                                    pos, length, ENC_BIG_ENDIAN);
1923             }
1924           else
1925             {
1926               THROW (ReportedBoundsError);
1927             }
1928           break;
1929         case CAP_EXP_UNICAST_SID:
1930           if (length == 1)
1931             {
1932               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_exp_unicast_sid, tvb,
1933                                    pos, length, ENC_BIG_ENDIAN);
1934             }
1935           else
1936             {
1937               THROW (ReportedBoundsError);
1938             }
1939           break;
1940         case CAP_RNG_HOFF:
1941           if (length == 4)
1942             {
1943               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_rnghoff_cm, tvb,
1944                                    pos, length, ENC_BIG_ENDIAN);
1945               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_rnghoff_erouter, tvb,
1946                                    pos, length, ENC_BIG_ENDIAN);
1947               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_rnghoff_emta, tvb,
1948                                    pos, length, ENC_BIG_ENDIAN);
1949               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_rnghoff_estb, tvb,
1950                                    pos, length, ENC_BIG_ENDIAN);
1951             }
1952           else
1953             {
1954               THROW (ReportedBoundsError);
1955             }
1956           break;
1957         case CAP_L2VPN:
1958           proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_l2vpn, tvb,
1959                                 pos, length, ENC_NA);
1960           break;
1961         case CAP_L2VPN_ESAFE:
1962           proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_l2vpn_esafe, tvb,
1963                                 pos, length, ENC_NA);
1964           break;
1965         case CAP_DUT_FILTERING:
1966           proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_dut_filtering, tvb,
1967                                 pos, length, ENC_NA);
1968           break;
1969         case CAP_US_FREQ_RNG:
1970           if (length == 1)
1971             {
1972               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_us_freq_range, tvb,
1973                                    pos, length, ENC_BIG_ENDIAN);
1974             }
1975           else
1976             {
1977               THROW (ReportedBoundsError);
1978             }
1979           break;
1980         case CAP_US_SRATE:
1981           if (length == 1)
1982             {
1983               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_us_srate_160, tvb,
1984                                    pos, length, ENC_BIG_ENDIAN);
1985               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_us_srate_320, tvb,
1986                                    pos, length, ENC_BIG_ENDIAN);
1987               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_us_srate_640, tvb,
1988                                    pos, length, ENC_BIG_ENDIAN);
1989               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_us_srate_1280, tvb,
1990                                    pos, length, ENC_BIG_ENDIAN);
1991               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_us_srate_2560, tvb,
1992                                    pos, length, ENC_BIG_ENDIAN);
1993               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_us_srate_5120, tvb,
1994                                    pos, length, ENC_BIG_ENDIAN);
1995             }
1996           else
1997             {
1998               THROW (ReportedBoundsError);
1999             }
2000           break;
2001         case CAP_SAC:
2002           if (length == 1)
2003             {
2004               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_sac, tvb,
2005                                    pos, length, ENC_BIG_ENDIAN);
2006             }
2007           else
2008             {
2009               THROW (ReportedBoundsError);
2010             }
2011           break;
2012         case CAP_CODE_HOP_M2:
2013           if (length == 1)
2014             {
2015               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_code_hop_mode2, tvb,
2016                                    pos, length, ENC_BIG_ENDIAN);
2017             }
2018           else
2019             {
2020               THROW (ReportedBoundsError);
2021             }
2022           break;
2023         case CAP_MTC:
2024           if (length == 1)
2025             {
2026               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_mtc, tvb,
2027                                    pos, length, ENC_BIG_ENDIAN);
2028             }
2029           else
2030             {
2031               THROW (ReportedBoundsError);
2032             }
2033           break;
2034         case CAP_512_MSPS_UTC:
2035           if (length == 1)
2036             {
2037               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_512_msps_utc, tvb,
2038                                    pos, length, ENC_BIG_ENDIAN);
2039             }
2040           else
2041             {
2042               THROW (ReportedBoundsError);
2043             }
2044           break;
2045         case CAP_256_MSPS_UTC:
2046           if (length == 1)
2047             {
2048               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_256_msps_utc, tvb,
2049                                    pos, length, ENC_BIG_ENDIAN);
2050             }
2051           else
2052             {
2053               THROW (ReportedBoundsError);
2054             }
2055           break;
2056         case CAP_TOTAL_SID_CLUST:
2057           if (length == 1)
2058             {
2059               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_total_sid_cluster, tvb,
2060                                    pos, length, ENC_BIG_ENDIAN);
2061             }
2062           else
2063             {
2064               THROW (ReportedBoundsError);
2065             }
2066           break;
2067         case CAP_SID_PER_SF:
2068           if (length == 1)
2069             {
2070               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_sid_per_sf, tvb,
2071                                    pos, length, ENC_BIG_ENDIAN);
2072             }
2073           else
2074             {
2075               THROW (ReportedBoundsError);
2076             }
2077           break;
2078         case CAP_MRC:
2079           if (length == 1)
2080             {
2081               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_mrc, tvb,
2082                                    pos, length, ENC_BIG_ENDIAN);
2083             }
2084           else
2085             {
2086               THROW (ReportedBoundsError);
2087             }
2088           break;
2089         case CAP_TOTAL_DSID:
2090           if (length == 1)
2091             {
2092               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_total_dsid, tvb,
2093                                    pos, length, ENC_BIG_ENDIAN);
2094             }
2095           else
2096             {
2097               THROW (ReportedBoundsError);
2098             }
2099           break;
2100         case CAP_RESEQ_DSID:
2101           if (length == 1)
2102             {
2103               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_reseq_dsid, tvb,
2104                                    pos, length, ENC_BIG_ENDIAN);
2105             }
2106           else
2107             {
2108               THROW (ReportedBoundsError);
2109             }
2110           break;
2111         case CAP_MC_DSID:
2112           if (length == 1)
2113             {
2114               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_mc_dsid, tvb,
2115                                    pos, length, ENC_BIG_ENDIAN);
2116             }
2117           else
2118             {
2119               THROW (ReportedBoundsError);
2120             }
2121           break;
2122         case CAP_MC_DSID_FWD:
2123           if (length == 1)
2124             {
2125               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_mc_dsid_fwd, tvb,
2126                                    pos, length, ENC_BIG_ENDIAN);
2127             }
2128           else
2129             {
2130               THROW (ReportedBoundsError);
2131             }
2132           break;
2133         case CAP_FCTYPE_FWD:
2134           if (length == 1)
2135             {
2136               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_fctype_fwd, tvb,
2137                                    pos, length, ENC_BIG_ENDIAN);
2138             }
2139           else
2140             {
2141               THROW (ReportedBoundsError);
2142             }
2143           break;
2144         case CAP_DPV:
2145           if (length == 1)
2146             {
2147               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_dpv_path, tvb,
2148                                    pos, length, ENC_BIG_ENDIAN);
2149               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_dpv_packet, tvb,
2150                                    pos, length, ENC_BIG_ENDIAN);
2151             }
2152           else
2153             {
2154               THROW (ReportedBoundsError);
2155             }
2156           break;
2157         case CAP_UGS:
2158           if (length == 1)
2159             {
2160               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_ugs, tvb,
2161                                    pos, length, ENC_BIG_ENDIAN);
2162             }
2163           else
2164             {
2165               THROW (ReportedBoundsError);
2166             }
2167           break;
2168         case CAP_MAP_UCD:
2169           if (length == 1)
2170             {
2171               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_map_ucd, tvb,
2172                                    pos, length, ENC_BIG_ENDIAN);
2173             }
2174           else
2175             {
2176               THROW (ReportedBoundsError);
2177             }
2178           break;
2179         case CAP_UDC:
2180           if (length == 2)
2181             {
2182               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_udc, tvb,
2183                                    pos, length, ENC_BIG_ENDIAN);
2184             }
2185           else
2186             {
2187               THROW (ReportedBoundsError);
2188             }
2189           break;
2190         case CAP_IPV6:
2191           if (length == 1)
2192             {
2193               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_ipv6, tvb,
2194                                    pos, length, ENC_BIG_ENDIAN);
2195             }
2196           else
2197             {
2198               THROW (ReportedBoundsError);
2199             }
2200           break;
2201         case CAP_EXT_US_TRNS_PWR:
2202           if (length == 1)
2203             {
2204               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_ext_us_trans_power, tvb,
2205                                    pos, length, ENC_BIG_ENDIAN);
2206             }
2207           else
2208             {
2209               THROW (ReportedBoundsError);
2210             }
2211           break;
2212         }                       /* switch (type) */
2213       pos = pos + length;
2214     }                           /* while (pos < pos+len) */
2215
2216 }
2217
2218 static void
2219 dissect_cos (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
2220 {
2221   guint8 type, length;
2222   proto_item *it;
2223   proto_tree *cos_tree;
2224   int pos = start;
2225
2226   it =
2227     proto_tree_add_text (tree, tvb, start, len,
2228                          "4 Class of Service Type (Length = %u)", len);
2229   cos_tree = proto_item_add_subtree (it, ett_docsis_tlv_cos);
2230
2231   while (pos < (start + len))
2232     {
2233       type = tvb_get_guint8 (tvb, pos++);
2234       length = tvb_get_guint8 (tvb, pos++);
2235       switch (type)
2236         {
2237         case COS_CLASSID:
2238           if (length == 1)
2239             {
2240               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_id, tvb, pos,
2241                                    length, ENC_BIG_ENDIAN);
2242             }
2243           else
2244             {
2245               THROW (ReportedBoundsError);
2246             }
2247           break;
2248         case COS_MAX_DOWN:
2249           if (length == 4)
2250             {
2251               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_max_down, tvb,
2252                                    pos, length, ENC_BIG_ENDIAN);
2253             }
2254           else
2255             {
2256               THROW (ReportedBoundsError);
2257             }
2258           break;
2259         case COS_MAX_UP:
2260           if (length == 4)
2261             {
2262               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_max_up, tvb,
2263                                    pos, length, ENC_BIG_ENDIAN);
2264             }
2265           else
2266             {
2267               THROW (ReportedBoundsError);
2268             }
2269           break;
2270         case COS_UP_CH_PRIO:
2271           if (length == 1)
2272             {
2273               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_up_chnl_pri,
2274                                    tvb, pos, length, ENC_BIG_ENDIAN);
2275             }
2276           else
2277             {
2278               THROW (ReportedBoundsError);
2279             }
2280           break;
2281         case COS_MIN_UP_RATE:
2282           if (length == 4)
2283             {
2284               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_min_grntd_up,
2285                                    tvb, pos, length, ENC_BIG_ENDIAN);
2286             }
2287           else
2288             {
2289               THROW (ReportedBoundsError);
2290             }
2291           break;
2292         case COS_MAX_UP_BURST:
2293           if (length == 2)
2294             {
2295               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_max_up_burst,
2296                                    tvb, pos, length, ENC_BIG_ENDIAN);
2297             }
2298           else
2299             {
2300               THROW (ReportedBoundsError);
2301             }
2302           break;
2303         case COS_BP_ENABLE:
2304           if (length == 1)
2305             {
2306               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_privacy_enable,
2307                                    tvb, pos, length, ENC_BIG_ENDIAN);
2308             }
2309           else
2310             {
2311               THROW (ReportedBoundsError);
2312
2313             }
2314           break;
2315         }                       /* switch (type) */
2316       pos = pos + length;
2317     }                           /* while (pos < pos+len) */
2318
2319 }
2320
2321 static void
2322 dissect_svc_unavail(tvbuff_t * tvb, proto_tree * tree, int pos, guint16 length) {
2323
2324   proto_item *svc_unavail_it;
2325   proto_tree *svc_unavail_tree;
2326   svc_unavail_it = proto_tree_add_item (tree,
2327                                         hf_docsis_tlv_svc_unavail,
2328                                         tvb, pos, length, ENC_NA);
2329   svc_unavail_tree = proto_item_add_subtree(svc_unavail_it, ett_docsis_tlv_svc_unavail );
2330   proto_tree_add_item (svc_unavail_tree,
2331                        hf_docsis_tlv_svc_unavail_classid, tvb,
2332                        pos, 1, ENC_BIG_ENDIAN);
2333   proto_tree_add_item (svc_unavail_tree,
2334                        hf_docsis_tlv_svc_unavail_type, tvb,
2335                        pos+1, 1, ENC_BIG_ENDIAN);
2336   proto_tree_add_item (svc_unavail_tree,
2337                        hf_docsis_tlv_svc_unavail_code, tvb,
2338                        pos+2, 1, ENC_BIG_ENDIAN);
2339
2340 }
2341
2342 static void
2343 dissect_snmpv3_kickstart(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len) {
2344   proto_item *snmpv3_it;
2345   proto_tree *snmpv3_tree;
2346   guint8 type, length;
2347   int pos = start;
2348
2349   snmpv3_it = proto_tree_add_item (tree,
2350                                    hf_docsis_tlv_snmpv3_kick,
2351                                    tvb, start, len, ENC_NA);
2352   snmpv3_tree = proto_item_add_subtree(snmpv3_it, ett_docsis_tlv_snmpv3_kick);
2353
2354   while (pos < (start + len))
2355     {
2356       type = tvb_get_guint8 (tvb, pos++);
2357       length = tvb_get_guint8 (tvb, pos++);
2358       switch (type)
2359         {
2360         case SNMPV3_SEC_NAME:
2361           proto_tree_add_item (snmpv3_tree,
2362                                hf_docsis_tlv_snmpv3_kick_name, tvb,
2363                                pos, length, ENC_ASCII|ENC_NA);
2364           break;
2365         case SNMPV3_MGR_PUB_NUM:
2366           proto_tree_add_item (snmpv3_tree,
2367                                hf_docsis_tlv_snmpv3_kick_publicnum, tvb,
2368                                pos, length, ENC_NA);
2369           break;
2370         }  /* switch */
2371       pos += length;
2372     }   /* while */
2373 }
2374
2375 static void
2376 dissect_ds_ch_list_single (tvbuff_t * tvb, proto_tree * tree,
2377                            int start, guint16 len)
2378 {
2379   guint8 type, length;
2380   proto_item *it;
2381   proto_tree *single_tree;
2382   int pos = start;
2383   it =
2384     proto_tree_add_text (tree, tvb, start, len,
2385                          "1 Single Downstream Channel (Length = %u)", len);
2386   single_tree = proto_item_add_subtree (it, ett_docsis_tlv_ds_ch_list_single);
2387
2388   while (pos < (start + len))
2389     {
2390       type = tvb_get_guint8 (tvb, pos++);
2391       length = tvb_get_guint8 (tvb, pos++);
2392       switch (type)
2393         {
2394         case SINGLE_CH_TIMEOUT:
2395           if (length == 2)
2396             {
2397               proto_tree_add_item (single_tree, hf_docsis_tlv_single_ch_timeout, tvb,
2398                                    pos, length, ENC_BIG_ENDIAN);
2399             }
2400           else
2401             {
2402               THROW (ReportedBoundsError);
2403             }
2404           break;
2405         case SINGLE_CH_FREQ:
2406           if (length == 4)
2407             {
2408               proto_tree_add_item (single_tree, hf_docsis_tlv_single_ch_freq, tvb,
2409                                    pos, length, ENC_BIG_ENDIAN);
2410             }
2411           else
2412             {
2413               THROW (ReportedBoundsError);
2414             }
2415           break;
2416         }  /* switch */
2417       pos = pos + length;
2418     }                           /* while */
2419 }
2420
2421 static void
2422 dissect_ds_ch_list_range (tvbuff_t * tvb, proto_tree * tree,
2423                           int start, guint16 len)
2424 {
2425   guint8 type, length;
2426   proto_item *it;
2427   proto_tree *range_tree;
2428   int pos = start;
2429   it =
2430     proto_tree_add_text (tree, tvb, start, len,
2431                          "2 Downstream Frequency Range (Length = %u)", len);
2432   range_tree = proto_item_add_subtree (it, ett_docsis_tlv_ds_ch_list_range);
2433
2434   while (pos < (start + len))
2435     {
2436       type = tvb_get_guint8 (tvb, pos++);
2437       length = tvb_get_guint8 (tvb, pos++);
2438       switch (type)
2439         {
2440         case FREQ_RNG_TIMEOUT:
2441           if (length == 2)
2442             {
2443               proto_tree_add_item (range_tree, hf_docsis_tlv_freq_rng_timeout, tvb,
2444                                    pos, length, ENC_BIG_ENDIAN);
2445             }
2446           else
2447             {
2448               THROW (ReportedBoundsError);
2449             }
2450           break;
2451         case FREQ_RNG_START:
2452           if (length == 4)
2453             {
2454               proto_tree_add_item (range_tree, hf_docsis_tlv_freq_rng_start, tvb,
2455                                    pos, length, ENC_BIG_ENDIAN);
2456             }
2457           else
2458             {
2459               THROW (ReportedBoundsError);
2460             }
2461           break;
2462         case FREQ_RNG_END:
2463           if (length == 4)
2464             {
2465               proto_tree_add_item (range_tree, hf_docsis_tlv_freq_rng_end, tvb,
2466                                    pos, length, ENC_BIG_ENDIAN);
2467             }
2468           else
2469             {
2470               THROW (ReportedBoundsError);
2471             }
2472           break;
2473         case FREQ_RNG_STEP:
2474           if (length == 4)
2475             {
2476               proto_tree_add_item (range_tree, hf_docsis_tlv_freq_rng_step, tvb,
2477                                    pos, length, ENC_BIG_ENDIAN);
2478             }
2479           else
2480             {
2481               THROW (ReportedBoundsError);
2482             }
2483           break;
2484         }                           /* switch */
2485       pos = pos + length;
2486     }                             /* while */
2487 }
2488
2489 static void
2490 dissect_dut_filter (tvbuff_t * tvb, proto_tree * tree,
2491                     int start, guint16 len)
2492 {
2493   guint8 type, length;
2494   proto_item *it;
2495   proto_tree *dut_tree;
2496   int pos = start;
2497   it =
2498     proto_tree_add_text (tree, tvb, start, len,
2499                          "Downstream Unencrypted Traffic (Length = %u)", len);
2500   dut_tree = proto_item_add_subtree (it, ett_docsis_tlv_dut_filter);
2501
2502   while (pos < (start + len))
2503     {
2504       type = tvb_get_guint8 (tvb, pos++);
2505       length = tvb_get_guint8 (tvb, pos++);
2506       switch (type)
2507         {
2508         case DUT_CONTROL:
2509           if (length == 1)
2510             {
2511               proto_tree_add_item (dut_tree, hf_docsis_tlv_dut_filter_control, tvb,
2512                                    pos, length, ENC_BIG_ENDIAN);
2513             }
2514           else
2515             {
2516               THROW (ReportedBoundsError);
2517             }
2518           break;
2519         case DUT_CMIM:
2520           proto_tree_add_item (dut_tree, hf_docsis_tlv_dut_filter_cmim, tvb,
2521                                    pos, length, ENC_NA);
2522           break;
2523         }                       /* switch */
2524       pos = pos + length;
2525     }                           /* while */
2526 }
2527
2528 static void
2529 dissect_ds_ch_list(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
2530 {
2531   guint8 type, length;
2532   proto_item *it;
2533   proto_tree *dschlst_tree;
2534   int pos = start;
2535   it =
2536     proto_tree_add_text (tree, tvb, start, len,
2537                          "41 Downstream Channel List (Length = %u)", len);
2538   dschlst_tree = proto_item_add_subtree (it, ett_docsis_tlv_ds_ch_list);
2539
2540   while (pos < (start + len))
2541     {
2542       type = tvb_get_guint8 (tvb, pos++);
2543       length = tvb_get_guint8 (tvb, pos++);
2544       switch (type)
2545         {
2546         case DS_CH_LIST_SINGLE:
2547       dissect_ds_ch_list_single(tvb, dschlst_tree, pos, length);
2548           break;
2549         case DS_CH_LIST_RANGE:
2550       dissect_ds_ch_list_range(tvb, dschlst_tree, pos, length);
2551           break;
2552         case DS_CH_LIST_DEFAULT_TIMEOUT:
2553           if (length == 2)
2554             {
2555               proto_tree_add_item (dschlst_tree,
2556                                    hf_docsis_tlv_ds_ch_list_default_timeout, tvb, pos,
2557                                    length, ENC_BIG_ENDIAN);
2558             }
2559           else
2560             {
2561               THROW (ReportedBoundsError);
2562             }
2563           break;
2564         }                       /* switch */
2565       pos = pos + length;
2566     }                           /* while */
2567 }
2568
2569 static void
2570 dissect_tcc_err(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
2571 {
2572   guint8 type, length;
2573   proto_item *it;
2574   proto_tree *tccerr_tree;
2575   int pos = start;
2576   it =
2577     proto_tree_add_text (tree, tvb, start, len,
2578                          "TCC Error Encodings (Length = %u)", len);
2579   tccerr_tree = proto_item_add_subtree (it, ett_docsis_tlv_tcc_err);
2580
2581   while (pos < (start + len))
2582     {
2583       type = tvb_get_guint8 (tvb, pos++);
2584       length = tvb_get_guint8 (tvb, pos++);
2585       switch (type)
2586         {
2587         case TCC_ERR_SUBTYPE:
2588           proto_tree_add_item (tccerr_tree,
2589                                hf_docsis_tcc_err_subtype, tvb,
2590                                pos, length, ENC_NA);
2591           break;
2592         case TCC_ERR_CODE:
2593           if (length == 1)
2594             {
2595               proto_tree_add_item (tccerr_tree,
2596                                    hf_docsis_tcc_err_code, tvb, pos,
2597                                    length, ENC_BIG_ENDIAN);
2598             }
2599           else
2600             {
2601               THROW (ReportedBoundsError);
2602             }
2603           break;
2604         case TCC_ERR_MSG:
2605           proto_tree_add_item (tccerr_tree,
2606                                hf_docsis_tcc_err_msg, tvb,
2607                                pos, length, ENC_ASCII|ENC_NA);
2608           break;
2609         }                       /* switch */
2610       pos = pos + length;
2611     }                           /* while */
2612 }
2613
2614 static void
2615 dissect_tcc_rng_parms(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
2616 {
2617   guint8 type, length;
2618   proto_item *it;
2619   proto_tree *rngparm_tree;
2620   int pos = start;
2621   it =
2622     proto_tree_add_text (tree, tvb, start, len,
2623                          "Ranging Parameters (Length = %u)", len);
2624   rngparm_tree = proto_item_add_subtree (it, ett_docsis_tlv_tcc_rng_parms);
2625
2626   while (pos < (start + len))
2627     {
2628       type = tvb_get_guint8 (tvb, pos++);
2629       length = tvb_get_guint8 (tvb, pos++);
2630       switch (type)
2631         {
2632         case RNG_PARMS_US_CH_ID:
2633           if (length == 1)
2634             {
2635               proto_tree_add_item (rngparm_tree,
2636                                    hf_docsis_rng_parms_us_ch_id, tvb, pos,
2637                                    length, ENC_BIG_ENDIAN);
2638             }
2639           else
2640             {
2641               THROW (ReportedBoundsError);
2642             }
2643           break;
2644         case RNG_PARMS_TIME_OFF_INT:
2645           if (length == 4)
2646             {
2647               proto_tree_add_item (rngparm_tree,
2648                                    hf_docsis_rng_parms_time_off_int, tvb, pos,
2649                                    length, ENC_BIG_ENDIAN);
2650             }
2651           else
2652             {
2653               THROW (ReportedBoundsError);
2654             }
2655           break;
2656         case RNG_PARMS_TIME_OFF_FRAC:
2657           if (length == 1)
2658             {
2659               proto_tree_add_item (rngparm_tree,
2660                                    hf_docsis_rng_parms_time_off_frac, tvb, pos,
2661                                    length, ENC_BIG_ENDIAN);
2662             }
2663           else
2664             {
2665               THROW (ReportedBoundsError);
2666             }
2667           break;
2668         case RNG_PARMS_POWER_OFF:
2669           if (length == 1)
2670             {
2671               proto_tree_add_item (rngparm_tree,
2672                                    hf_docsis_rng_parms_power_off, tvb, pos,
2673                                    length, ENC_BIG_ENDIAN);
2674             }
2675           else
2676             {
2677               THROW (ReportedBoundsError);
2678             }
2679           break;
2680         case RNG_PARMS_FREQ_OFF:
2681           if (length == 1)
2682             {
2683               proto_tree_add_item (rngparm_tree,
2684                                    hf_docsis_rng_parms_freq_off, tvb, pos,
2685                                    length, ENC_BIG_ENDIAN);
2686             }
2687           else
2688             {
2689               THROW (ReportedBoundsError);
2690             }
2691           break;
2692         }                       /* switch */
2693       pos = pos + length;
2694     }                           /* while */
2695 }
2696
2697 static void
2698 dissect_sid_cl_so_crit(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
2699 {
2700   guint8 type, length;
2701   proto_item *it;
2702   proto_tree *crit_tree;
2703   int pos = start;
2704   it =
2705     proto_tree_add_text (tree, tvb, start, len,
2706                          "SID Cluster Switchover Criteria (Length = %u)", len);
2707   crit_tree = proto_item_add_subtree (it, ett_docsis_tlv_sid_cl_so);
2708
2709   while (pos < (start + len))
2710     {
2711       type = tvb_get_guint8 (tvb, pos++);
2712       length = tvb_get_guint8 (tvb, pos++);
2713       switch (type)
2714         {
2715         case SID_CL_SO_MAX_REQ:
2716           if (length == 1)
2717             {
2718               proto_tree_add_item (crit_tree,
2719                                    hf_docsis_sid_cl_so_max_req, tvb, pos,
2720                                    length, ENC_BIG_ENDIAN);
2721             }
2722           else
2723             {
2724               THROW (ReportedBoundsError);
2725             }
2726           break;
2727         case SID_CL_SO_MAX_OUT_BYTES:
2728           if (length == 4)
2729             {
2730               proto_tree_add_item (crit_tree,
2731                                    hf_docsis_sid_cl_so_max_out_bytes, tvb, pos,
2732                                    length, ENC_BIG_ENDIAN);
2733             }
2734           else
2735             {
2736               THROW (ReportedBoundsError);
2737             }
2738           break;
2739         case SID_CL_SO_MAX_REQ_BYTES:
2740           if (length == 4)
2741             {
2742               proto_tree_add_item (crit_tree,
2743                                    hf_docsis_sid_cl_so_max_req_bytes, tvb, pos,
2744                                    length, ENC_BIG_ENDIAN);
2745             }
2746           else
2747             {
2748               THROW (ReportedBoundsError);
2749             }
2750           break;
2751         case SID_CL_SO_MAX_TIME:
2752           if (length == 2)
2753             {
2754               proto_tree_add_item (crit_tree,
2755                                    hf_docsis_sid_cl_so_max_time, tvb, pos,
2756                                    length, ENC_BIG_ENDIAN);
2757             }
2758           else
2759             {
2760               THROW (ReportedBoundsError);
2761             }
2762           break;
2763         }                       /* switch */
2764       pos = pos + length;
2765     }                           /* while */
2766 }
2767
2768 static void
2769 dissect_sid_cl_enc_map(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
2770 {
2771   guint8 type, length;
2772   proto_item *it;
2773   proto_tree *map_tree;
2774   int pos = start;
2775   it =
2776     proto_tree_add_text (tree, tvb, start, len,
2777                          "SID-to-Channel Mapping (Length = %u)", len);
2778   map_tree = proto_item_add_subtree (it, ett_docsis_tlv_sid_cl_enc_map);
2779
2780   while (pos < (start + len))
2781     {
2782       type = tvb_get_guint8 (tvb, pos++);
2783       length = tvb_get_guint8 (tvb, pos++);
2784       switch (type)
2785         {
2786         case SID_CL_MAP_US_CH_ID:
2787           if (length == 1)
2788             {
2789               proto_tree_add_item (map_tree,
2790                                    hf_docsis_sid_cl_map_us_ch_id, tvb, pos,
2791                                    length, ENC_BIG_ENDIAN);
2792             }
2793           else
2794             {
2795               THROW (ReportedBoundsError);
2796             }
2797           break;
2798         case SID_CL_MAP_SID:
2799           if (length == 2)
2800             {
2801               proto_tree_add_item (map_tree,
2802                                    hf_docsis_sid_cl_map_sid, tvb, pos,
2803                                    length, ENC_BIG_ENDIAN);
2804             }
2805           else
2806             {
2807               THROW (ReportedBoundsError);
2808             }
2809           break;
2810         case SID_CL_MAP_ACTION:
2811           if (length == 1)
2812             {
2813               proto_tree_add_item (map_tree,
2814                                    hf_docsis_sid_cl_map_action, tvb, pos,
2815                                    length, ENC_BIG_ENDIAN);
2816             }
2817           else
2818             {
2819               THROW (ReportedBoundsError);
2820             }
2821           break;
2822         }                       /* switch */
2823       pos = pos + length;
2824     }                           /* while */
2825 }
2826
2827 static void
2828 dissect_sid_cl_enc(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
2829 {
2830   guint8 type, length;
2831   proto_item *it;
2832   proto_tree *enc_tree;
2833   int pos = start;
2834   it =
2835     proto_tree_add_text (tree, tvb, start, len,
2836                          "SID Cluster Encoding (Length = %u)", len);
2837   enc_tree = proto_item_add_subtree (it, ett_docsis_tlv_sid_cl_enc);
2838
2839   while (pos < (start + len))
2840     {
2841       type = tvb_get_guint8 (tvb, pos++);
2842       length = tvb_get_guint8 (tvb, pos++);
2843       switch (type)
2844         {
2845         case SID_CL_ENC_ID:
2846           if (length == 1)
2847             {
2848               proto_tree_add_item (enc_tree,
2849                                    hf_docsis_sid_cl_enc_id, tvb, pos,
2850                                    length, ENC_BIG_ENDIAN);
2851             }
2852           else
2853             {
2854               THROW (ReportedBoundsError);
2855             }
2856           break;
2857         case SID_CL_ENC_MAP:
2858           if (length == 10)
2859              dissect_sid_cl_enc_map(tvb, enc_tree, pos, length);
2860           else
2861               THROW (ReportedBoundsError);
2862           break;
2863         }                       /* switch */
2864       pos = pos + length;
2865     }                           /* while */
2866 }
2867
2868 static void
2869 dissect_sid_cl(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
2870 {
2871   guint8 type, length;
2872   proto_item *it;
2873   proto_tree *sid_tree;
2874   int pos = start;
2875   it =
2876     proto_tree_add_text (tree, tvb, start, len,
2877                          "47 Service Flow SID Cluster Assignments (Length = %u)", len);
2878   sid_tree = proto_item_add_subtree (it, ett_docsis_tlv_sid_cl);
2879
2880   while (pos < (start + len))
2881     {
2882       type = tvb_get_guint8 (tvb, pos++);
2883       length = tvb_get_guint8 (tvb, pos++);
2884       switch (type)
2885         {
2886         case SID_CL_SF_ID:
2887           if (length == 4)
2888             {
2889               proto_tree_add_item (sid_tree,
2890                                    hf_docsis_sid_cl_sf_id, tvb, pos,
2891                                    length, ENC_BIG_ENDIAN);
2892             }
2893           else
2894             {
2895               THROW (ReportedBoundsError);
2896             }
2897           break;
2898         case SID_CL_ENC:
2899           dissect_sid_cl_enc(tvb, sid_tree, pos, length);
2900           break;
2901         case SID_CL_SO_CRIT:
2902           dissect_sid_cl_so_crit(tvb, sid_tree, pos, length);
2903           break;
2904         }                       /* switch */
2905       pos = pos + length;
2906     }                           /* while */
2907 }
2908
2909 static void
2910 dissect_tcc(tvbuff_t * tvb, packet_info * pinfo _U_,
2911             proto_tree *tree, int start, guint16 len)
2912 {
2913   guint8 type, length;
2914   proto_item *it;
2915   proto_tree *tcc_tree;
2916   int pos = start;
2917   tvbuff_t *ucd_tvb;
2918
2919   it =
2920     proto_tree_add_text (tree, tvb, start, len,
2921                          "46 Transmit Channel Configuration (Length = %u)", len);
2922   tcc_tree = proto_item_add_subtree (it, ett_docsis_tlv_tcc);
2923
2924   while (pos < (start + len))
2925     {
2926       type = tvb_get_guint8 (tvb, pos++);
2927       length = tvb_get_guint8 (tvb, pos++);
2928       switch (type)
2929         {
2930         case TLV_TCC_REFID:
2931           if (length == 1)
2932             {
2933               proto_tree_add_item (tcc_tree,
2934                                    hf_docsis_tlv_tcc_refid, tvb, pos,
2935                                    length, ENC_BIG_ENDIAN);
2936             }
2937           else
2938             {
2939               THROW (ReportedBoundsError);
2940             }
2941           break;
2942         case TLV_TCC_US_CH_ACTION:
2943           if (length == 1)
2944             {
2945               proto_tree_add_item (tcc_tree,
2946                                    hf_docsis_tlv_tcc_us_ch_action, tvb, pos,
2947                                    length, ENC_BIG_ENDIAN);
2948             }
2949           else
2950             {
2951               THROW (ReportedBoundsError);
2952             }
2953           break;
2954         case TLV_TCC_US_CH_ID:
2955           if (length == 1)
2956             {
2957               proto_tree_add_item (tcc_tree,
2958                                    hf_docsis_tlv_tcc_us_ch_id, tvb, pos,
2959                                    length, ENC_BIG_ENDIAN);
2960             }
2961           else
2962             {
2963               THROW (ReportedBoundsError);
2964             }
2965           break;
2966         case TLV_TCC_NEW_US_CH_ID:
2967           if (length == 1)
2968             {
2969               proto_tree_add_item (tcc_tree,
2970                                    hf_docsis_tlv_tcc_new_us_ch_id, tvb, pos,
2971                                    length, ENC_BIG_ENDIAN);
2972             }
2973           else
2974             {
2975               THROW (ReportedBoundsError);
2976             }
2977           break;
2978         case TLV_TCC_UCD:
2979           ucd_tvb = tvb_new_subset (tvb, pos, length, length);
2980           call_dissector (docsis_ucd_handle, ucd_tvb, pinfo, tcc_tree);
2981           break;
2982         case TLV_TCC_RNG_SID:
2983           if (length == 2)
2984             {
2985               proto_tree_add_item (tcc_tree,
2986                                    hf_docsis_tlv_tcc_rng_sid, tvb, pos,
2987                                    length, ENC_BIG_ENDIAN);
2988             }
2989           else
2990             {
2991               THROW (ReportedBoundsError);
2992             }
2993           break;
2994         case TLV_TCC_INIT_TECH:
2995           if (length == 1)
2996             {
2997               proto_tree_add_item (tcc_tree,
2998                                    hf_docsis_tlv_tcc_init_tech, tvb, pos,
2999                                    length, ENC_BIG_ENDIAN);
3000             }
3001           else
3002             {
3003               THROW (ReportedBoundsError);
3004             }
3005           break;
3006         case TLV_TCC_RNG_PARMS:
3007           dissect_tcc_rng_parms(tvb, tcc_tree, pos, length);
3008           break;
3009         case TLV_TCC_DYN_RNG_WIN:
3010           if (length == 1)
3011             {
3012               proto_tree_add_item (tcc_tree,
3013                                    hf_docsis_tlv_tcc_dyn_rng_win, tvb, pos,
3014                                    length, ENC_BIG_ENDIAN);
3015             }
3016           else
3017             {
3018               THROW (ReportedBoundsError);
3019             }
3020           break;
3021         case TLV_TCC_ERR:
3022           dissect_tcc_err(tvb, tcc_tree, pos, length);
3023           break;
3024         }                       /* switch */
3025       pos = pos + length;
3026     }                           /* while */
3027 }
3028
3029 static void
3030 dissect_ch_bl_rng(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
3031 {
3032   guint8 type, length;
3033   proto_item *it;
3034   proto_tree *chblrng_tree;
3035   int pos = start;
3036   it =
3037     proto_tree_add_text (tree, tvb, start, len,
3038                          "Receive Module Channel Block Range (Length = %u)", len);
3039   chblrng_tree = proto_item_add_subtree (it, ett_docsis_tlv_rcp_ch_bl_rng);
3040
3041   while (pos < (start + len))
3042     {
3043       type = tvb_get_guint8 (tvb, pos++);
3044       length = tvb_get_guint8 (tvb, pos++);
3045       switch (type)
3046         {
3047         case CH_BL_RNG_MIN_CTR_FREQ:
3048           if (length == 4)
3049             {
3050               proto_tree_add_item (chblrng_tree,
3051                                    hf_docsis_ch_bl_rng_min_ctr_freq, tvb, pos,
3052                                    length, ENC_BIG_ENDIAN);
3053             }
3054           else
3055             {
3056               THROW (ReportedBoundsError);
3057             }
3058           break;
3059         case CH_BL_RNG_MAX_CTR_FREQ:
3060           if (length == 4)
3061             {
3062               proto_tree_add_item (chblrng_tree,
3063                                    hf_docsis_ch_bl_rng_max_ctr_freq, tvb, pos,
3064                                    length, ENC_BIG_ENDIAN);
3065             }
3066           else
3067             {
3068               THROW (ReportedBoundsError);
3069             }
3070           break;
3071         }                       /* switch */
3072       pos = pos + length;
3073     }                           /* while */
3074 }
3075
3076 static void
3077 dissect_rcp_rcv_mod(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
3078 {
3079   guint8 type, length;
3080   proto_item *it;
3081   proto_tree *rcvmod_tree;
3082   int pos = start;
3083   it =
3084     proto_tree_add_text (tree, tvb, start, len,
3085                          "Receive Module Capability (Length = %u)", len);
3086   rcvmod_tree = proto_item_add_subtree (it, ett_docsis_tlv_rcp_rcv_mod_enc);
3087
3088   while (pos < (start + len))
3089     {
3090       type = tvb_get_guint8 (tvb, pos++);
3091       length = tvb_get_guint8 (tvb, pos++);
3092       switch (type)
3093         {
3094         case RCV_MOD_ENC_IDX:
3095           if (length == 1)
3096             {
3097               proto_tree_add_item (rcvmod_tree,
3098                                    hf_docsis_rcv_mod_enc_idx, tvb, pos,
3099                                    length, ENC_BIG_ENDIAN);
3100             }
3101           else
3102             {
3103               THROW (ReportedBoundsError);
3104             }
3105           break;
3106         case RCV_MOD_ENC_CH_BL_RNG:
3107           dissect_ch_bl_rng(tvb, rcvmod_tree, pos, length);
3108           break;
3109         case RCV_MOD_ENC_CTR_FREQ_ASGN:
3110           if (length == 4)
3111             {
3112               proto_tree_add_item (rcvmod_tree,
3113                                    hf_docsis_rcv_mod_enc_ctr_freq_asgn, tvb, pos,
3114                                    length, FALSE);
3115             }
3116           else
3117             {
3118               THROW (ReportedBoundsError);
3119             }
3120           break;
3121         case RCV_MOD_ENC_RSQ_CH_SUBS_CAP:
3122           proto_tree_add_item (rcvmod_tree,
3123                    hf_docsis_rcv_mod_enc_rsq_ch_subs_cap, tvb, pos,
3124                    length, ENC_NA);
3125           break;
3126         case RCV_MOD_ENC_CONN:
3127           proto_tree_add_item (rcvmod_tree,
3128                    hf_docsis_rcv_mod_enc_conn, tvb, pos,
3129                    length, ENC_NA);
3130           break;
3131         case RCV_MOD_ENC_PHY_LAYR_PARMS:
3132           proto_tree_add_item (rcvmod_tree,
3133                    hf_docsis_rcv_mod_enc_phy_layr_parms, tvb, pos,
3134                    length, ENC_NA);
3135           break;
3136         }                       /* switch */
3137       pos = pos + length;
3138     }                           /* while */
3139 }
3140
3141 static void
3142 dissect_rcp_rcv_ch(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len)
3143 {
3144   guint8 type, length;
3145   proto_item *it;
3146   proto_tree *rcvch_tree;
3147   int pos = start;
3148   it =
3149     proto_tree_add_text (tree, tvb, start, len,
3150                          "Receive Channels (Length = %u)", len);
3151   rcvch_tree = proto_item_add_subtree (it, ett_docsis_tlv_rcp_rcv_ch);
3152
3153   while (pos < (start + len))
3154     {
3155       type = tvb_get_guint8 (tvb, pos++);
3156       length = tvb_get_guint8 (tvb, pos++);
3157       switch (type)
3158         {
3159         case RCV_CH_IDX:
3160           if (length == 1)
3161             {
3162               proto_tree_add_item (rcvch_tree,
3163                                    hf_docsis_rcv_ch_idx, tvb, pos,
3164                                    length, ENC_BIG_ENDIAN);
3165             }
3166           else
3167             {
3168               THROW (ReportedBoundsError);
3169             }
3170           break;
3171         case RCV_CH_CONN:
3172           proto_tree_add_item (rcvch_tree,
3173                            hf_docsis_rcv_ch_conn, tvb, pos,
3174                            length, ENC_NA);
3175           break;
3176         case RCV_CH_CONN_OFF:
3177           if (length == 1)
3178             {
3179               proto_tree_add_item (rcvch_tree,
3180                                    hf_docsis_rcv_ch_conn_off, tvb, pos,
3181                                    length, ENC_BIG_ENDIAN);
3182             }
3183           else
3184             {
3185               THROW (ReportedBoundsError);
3186             }
3187           break;
3188         case RCV_CH_PRIM_DS_CH_IND:
3189           if (length == 1)
3190             {
3191               proto_tree_add_item (rcvch_tree,
3192                                    hf_docsis_rcv_ch_prim_ds_ch_ind, tvb, pos,
3193                                    length, ENC_BIG_ENDIAN);
3194             }
3195           else
3196             {
3197               THROW (ReportedBoundsError);
3198             }
3199           break;
3200         }                       /* switch */
3201       pos = pos + length;
3202     }                           /* while */
3203 }
3204
3205
3206 static void
3207 dissect_rcp(tvbuff_t * tvb, packet_info * pinfo _U_,
3208             proto_tree *tree, int start, guint16 len)
3209 {
3210   guint8 type, length;
3211   proto_item *it;
3212   proto_tree *rcp_tree;
3213   int pos = start;
3214   tvbuff_t *vsif_tvb;
3215
3216   it =
3217     proto_tree_add_text (tree, tvb, start, len,