From Didier Gautheron:
[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
43
44 static int proto_docsis_tlv = -1;
45 static int hf_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
90 static int hf_docsis_tlv_cos_id = -1;
91 static int hf_docsis_tlv_cos_sid = -1;
92 static int hf_docsis_tlv_cos_max_down = -1;
93 static int hf_docsis_tlv_cos_max_up = -1;
94 static int hf_docsis_tlv_cos_up_chnl_pri = -1;
95 static int hf_docsis_tlv_cos_min_grntd_up = -1;
96 static int hf_docsis_tlv_cos_max_up_burst = -1;
97 static int hf_docsis_tlv_cos_privacy_enable = -1;
98
99 static int hf_docsis_tlv_mcap_concat = -1;
100 static int hf_docsis_tlv_mcap_docs_ver = -1;
101 static int hf_docsis_tlv_mcap_frag = -1;
102 static int hf_docsis_tlv_mcap_phs = -1;
103 static int hf_docsis_tlv_mcap_igmp = -1;
104 static int hf_docsis_tlv_mcap_down_said = -1;
105 static int hf_docsis_tlv_mcap_up_sid = -1;
106 static int hf_docsis_tlv_mcap_privacy = -1;
107 static int hf_docsis_tlv_mcap_8021P_filter = -1;
108 static int hf_docsis_tlv_mcap_8021Q_filter = -1;
109 static int hf_docsis_tlv_mcap_xmit_eq_taps_per_sym = -1;
110 static int hf_docsis_tlv_mcap_xmit_eq_taps = -1;
111 static int hf_docsis_tlv_mcap_dcc = -1;
112
113 static int hf_docsis_tlv_clsfr_ref = -1;
114 static int hf_docsis_tlv_clsfr_id = -1;
115 static int hf_docsis_tlv_clsfr_sflow_ref = -1;
116 static int hf_docsis_tlv_clsfr_sflow_id = -1;
117 static int hf_docsis_tlv_clsfr_rule_pri = -1;
118 static int hf_docsis_tlv_clsfr_act_state = -1;
119 static int hf_docsis_tlv_clsfr_dsc_act = -1;
120 static int hf_docsis_tlv_clsfr_err = -1;
121 static int hf_docsis_tlv_ipclsfr = -1;
122 static int hf_docsis_tlv_ethclsfr = -1;
123 static int hf_docsis_tlv_dot1qclsfr = -1;
124
125 static int hf_docsis_tlv_clsfr_vendor_spc = -1;
126
127 static int hf_docsis_tlv_clsfr_err_param = -1;
128 static int hf_docsis_tlv_clsfr_err_code = -1;
129 static int hf_docsis_tlv_clsfr_err_msg = -1;
130
131 static int hf_docsis_tlv_ipclsfr_tosmask = -1;
132 static int hf_docsis_tlv_ipclsfr_ipproto = -1;
133 static int hf_docsis_tlv_ipclsfr_src = -1;
134 static int hf_docsis_tlv_ipclsfr_dst = -1;
135 static int hf_docsis_tlv_ipclsfr_srcmask = -1;
136 static int hf_docsis_tlv_ipclsfr_dstmask = -1;
137 static int hf_docsis_tlv_ipclsfr_sport_start = -1;
138 static int hf_docsis_tlv_ipclsfr_sport_end = -1;
139 static int hf_docsis_tlv_ipclsfr_dport_start = -1;
140 static int hf_docsis_tlv_ipclsfr_dport_end = -1;
141
142 static int hf_docsis_tlv_ethclsfr_dmac = -1;
143 static int hf_docsis_tlv_ethclsfr_smac = -1;
144 static int hf_docsis_tlv_ethclsfr_ethertype = -1;
145
146 static int hf_docsis_tlv_dot1qclsfr_user_pri = -1;
147 static int hf_docsis_tlv_dot1qclsfr_vlanid = -1;
148 static int hf_docsis_tlv_dot1qclsfr_vendorspec = -1;
149
150 static int hf_docsis_tlv_sflow_ref = -1;
151 static int hf_docsis_tlv_sflow_id = -1;
152 static int hf_docsis_tlv_sflow_sid = -1;
153 static int hf_docsis_tlv_sflow_classname = -1;
154 static int hf_docsis_tlv_sflow_qos_param = -1;
155 static int hf_docsis_tlv_sflow_err = -1;
156 static int hf_docsis_tlv_sflow_traf_pri = -1;
157 static int hf_docsis_tlv_sflow_max_sus = -1;
158 static int hf_docsis_tlv_sflow_max_burst = -1;
159 static int hf_docsis_tlv_sflow_min_traf = -1;
160 static int hf_docsis_tlv_sflow_ass_min_pkt_size = -1;
161 static int hf_docsis_tlv_sflow_timeout_active = -1;
162 static int hf_docsis_tlv_sflow_timeout_admitted = -1;
163 static int hf_docsis_tlv_sflow_vendor_spec = -1;
164 static int hf_docsis_tlv_sflow_max_concat_burst = -1;
165 static int hf_docsis_tlv_sflow_sched_type = -1;
166 static int hf_docsis_tlv_sflow_reqxmit_pol = -1;
167 static int hf_docsis_tlv_sflow_nominal_polling = -1;
168 static int hf_docsis_tlv_sflow_tolerated_jitter = -1;
169 static int hf_docsis_tlv_sflow_ugs_size = -1;
170 static int hf_docsis_tlv_sflow_nom_grant_intvl = -1;
171 static int hf_docsis_tlv_sflow_tol_grant_jitter = -1;
172 static int hf_docsis_tlv_sflow_grants_per_intvl = -1;
173 static int hf_docsis_tlv_sflow_ip_tos_overwrite = -1;
174 static int hf_docsis_tlv_sflow_ugs_timeref = -1;
175 static int hf_docsis_tlv_sflow_max_down_latency = -1;
176
177 static int hf_docsis_tlv_sflow_err_param = -1;
178 static int hf_docsis_tlv_sflow_err_code = -1;
179 static int hf_docsis_tlv_sflow_err_msg = -1;
180
181 static int hf_docsis_tlv_phs_class_ref = -1;
182 static int hf_docsis_tlv_phs_class_id = -1;
183 static int hf_docsis_tlv_phs_sflow_ref = -1;
184 static int hf_docsis_tlv_phs_sflow_id = -1;
185 static int hf_docsis_tlv_phs_dsc_action = -1;
186 static int hf_docsis_tlv_phs_err = -1;
187 static int hf_docsis_tlv_phs_phsf = -1;
188 static int hf_docsis_tlv_phs_phsm = -1;
189 static int hf_docsis_tlv_phs_phsv = -1;
190 static int hf_docsis_tlv_phs_phsi = -1;
191 static int hf_docsis_tlv_phs_phss = -1;
192 static int hf_docsis_tlv_phs_vendorspec = -1;
193
194 static int hf_docsis_tlv_phs_err_param = -1;
195 static int hf_docsis_tlv_phs_err_code = -1;
196 static int hf_docsis_tlv_phs_err_msg = -1;
197
198 /* Initialize the subtree pointers */
199 static gint ett_docsis_tlv = -1;
200 static gint ett_docsis_tlv_cos = -1;
201 static gint ett_docsis_tlv_mcap = -1;
202 static gint ett_docsis_tlv_clsfr = -1;
203 static gint ett_docsis_tlv_clsfr_ip = -1;
204 static gint ett_docsis_tlv_clsfr_eth = -1;
205 static gint ett_docsis_tlv_clsfr_err = -1;
206 static gint ett_docsis_tlv_phs = -1;
207 static gint ett_docsis_tlv_phs_err = -1;
208 static gint ett_docsis_tlv_clsfr_dot1q = -1;
209 static gint ett_docsis_tlv_reqxmitpol = -1;
210 static gint ett_docsis_tlv_sflow_err = -1;
211 static gint ett_docsis_tlv_svc_unavail = -1;
212 static gint ett_docsis_tlv_snmpv3_kick = -1;
213
214 static const true_false_string on_off_tfs = {
215   "On",
216   "Off"
217 };
218
219 static const value_string on_off_vals[] = {
220   {0, "Off"},
221   {1, "On"},
222   {0, NULL},
223 };
224
225 static const true_false_string ena_dis_tfs = {
226   "Enable",
227   "Disable"
228 };
229
230 static const value_string docs_ver_vals[] = {
231   {0, "v1.0"},
232   {1, "v1.1"},
233   {0, NULL},
234 };
235
236 static const true_false_string activation_tfs = {
237   "Active",
238   "Inactive"
239 };
240
241 static const value_string dsc_act_vals[] = {
242   {0, "DSC Add Classifier"},
243   {1, "DSC Replace Classifier"},
244   {2, "DSC Delete Classifier"},
245   {0, NULL},
246 };
247
248 static const value_string qos_param_vals[] = {
249   {0x01, "Apply to provisioned set only"},
250   {0x02, "Perform admission control add apply to admitted set"},
251   {0x03, "Apply to provisioned and admitted set; Perform admission control"},
252   {0x04, "Perform admission control if needed and apply to active set"},
253   {0x05,
254    "Apply to provisioned and active sets; Admission control on admitted set in separate service flow, and activate service flow"},
255   {0x06,
256    "Perform admission control and activate; Apply to admitted and active sets"},
257   {0x07,
258    "Apply to Provisioned, Active and Admitted Sets; Admission Control and Activate Service Flow"},
259   {0, NULL},
260 };
261
262 static const value_string sched_type_vals[] = {
263   {0, "Reserved"},
264   {1, "Undefined (CMTS Dependent)"},
265   {2, "Best Effort Service"},
266   {3, "Non-Real-Time Polling Service"},
267   {4, "Real-Time Polling Service"},
268   {5, "Unsolicited Grant Service w/Activity Detection"},
269   {6, "Unsolicited Grant Service"},
270   {0, NULL},
271 };
272
273 static const value_string action_vals[] = {
274   {0, "Add PHS Rule"},
275   {1, "Set PHS Rule"},
276   {2, "Delete PHS Rule"},
277   {3, "Delete all PHS Rules"},
278   {0, NULL},
279 };
280
281 static const true_false_string verify_tfs = {
282   "Don't Verify",
283   "Verify"
284 };
285
286 static const value_string rng_tech_vals[] = {
287   {0, "Perform initial maintenance on new channel"},
288   {1, "Perform only station maintenance on new channel"},
289   {2,
290    "Perform either initial maintenance or station maintenance on new channel"},
291   {3,
292    "Use the new channel directly without performing initial or station maintenance"},
293   {0, NULL},
294 };
295
296
297 const value_string docsis_conf_code[] = {
298   {0, "okay/success"},
299   {1, "Reject: Other/Auth failure (1.0)"},
300   {2, "Reject: Unrecognized configuration setting/COS failure (1.0)"},
301   {3, "Reject: Temporary/Reject resource"},
302   {4, "Reject: Permanent/Reject admin"},
303   {5, "Reject: Not owner"},
304   {6, "Reject: Service flow not found"},
305   {7, "Reject: Service flow exists"},
306   {8, "Reject: Required parameter not present"},
307   {9, "Reject: Header suppression"},
308   {10, "Reject: Unknown transaction id"},
309   {11, "Reject: Authentication failure"},
310   {12, "Reject: Add aborted"},
311   {13, "Reject: Multiple errors"},
312   {14, "Reject: Classifier not found"},
313   {15, "Reject: Classifier exists"},
314   {16, "Reject: PHS rule not found"},
315   {17, "Reject: PHS rule exists"},
316   {18, "Reject: Duplicate reference ID or index in message"},
317   {19, "Reject: Multiple upstream service flows"},
318   {20, "Reject: Multiple downstream service flows"},
319   {21, "Reject: Classifier for another service flow "},
320   {22, "Reject: PHS for another service flow "},
321   {23, "Reject: Parameter invalid for context"},
322   {24, "Reject: Authorization failure"},
323   {25, "Reject: Temporary DCC"},
324   {180, "Depart"},
325   {181, "Arrive"},
326   {182, "Reject: Already There"},
327   {200, "Reject: Major Service Flow Error"},
328   {201, "Reject: Major Classifier Error"},
329   {202, "Reject: Major PHS Rule Error"},
330   {203, "Reject: Multiple Major Errors"},
331   {204, "Reject: Message Syntax Error"},
332   {205, "Reject: Primary Service Flow Error"},
333   {206, "Reject: Message Too Big"},
334   {207, "Reject: Invalid Modem Capabilities"},
335   {0, NULL}
336 };
337
338
339
340 /* Code to actually dissect the packets */
341 static void
342 dissect_phs_err (tvbuff_t * tvb, proto_tree * tree, int start,
343                  guint16 len)
344 {
345   guint8 type, length;
346   proto_item *it;
347   proto_tree *err_tree;
348   int pos = start;
349   it =
350     proto_tree_add_text (tree, tvb, start, len,
351                          "5 Service Flow Error Encodings (Length = %u)", len);
352   err_tree = proto_item_add_subtree (it, ett_docsis_tlv_sflow_err);
353
354   while (pos < (start + len))
355     {
356       type = tvb_get_guint8 (tvb, pos++);
357       length = tvb_get_guint8 (tvb, pos++);
358       switch (type)
359         {
360         case PHS_ERR_PARAM:
361           if (length == 1)
362             {
363               proto_tree_add_item (err_tree, hf_docsis_tlv_phs_err_param, tvb,
364                                    pos, length, FALSE);
365             }
366           else
367             {
368               THROW (ReportedBoundsError);
369             }
370           break;
371         case PHS_ERR_CODE:
372           if (length == 1)
373             {
374               proto_tree_add_item (err_tree, hf_docsis_tlv_phs_err_code, tvb,
375                                    pos, length, FALSE);
376             }
377           else
378             {
379               THROW (ReportedBoundsError);
380             }
381           break;
382         case PHS_ERR_MSG:
383           proto_tree_add_item (err_tree, hf_docsis_tlv_phs_err_msg, tvb, pos,
384                                length, FALSE);
385           break;
386         }                       /* switch */
387       pos = pos + length;
388
389     }                           /* while */
390 }
391
392 static void
393 dissect_phs (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
394 {
395   guint8 type, length;
396   proto_item *it;
397   proto_tree *phs_tree;
398   int pos = start;
399   it =
400     proto_tree_add_text (tree, tvb, start, len,
401                          "26 PHS Encodings (Length = %u)", len);
402   phs_tree = proto_item_add_subtree (it, ett_docsis_tlv_phs);
403
404   while (pos < (start + len))
405     {
406       type = tvb_get_guint8 (tvb, pos++);
407       length = tvb_get_guint8 (tvb, pos++);
408       switch (type)
409         {
410         case PHS_CLSFR_REF:
411           if (length == 1)
412             {
413               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_class_ref, tvb,
414                                    pos, length, FALSE);
415             }
416           else
417             {
418               THROW (ReportedBoundsError);
419             }
420           break;
421         case PHS_CLSFR_ID:
422           if (length == 2)
423             {
424               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_class_id, tvb,
425                                    pos, length, FALSE);
426             }
427           else
428             {
429               THROW (ReportedBoundsError);
430             }
431           break;
432         case PHS_SFLOW_REF:
433           if (length == 2)
434             {
435               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_sflow_ref, tvb,
436                                    pos, length, FALSE);
437             }
438           else
439             {
440               THROW (ReportedBoundsError);
441             }
442           break;
443         case PHS_SFLOW_ID:
444           if (length == 4)
445             {
446               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_sflow_id, tvb,
447                                    pos, length, FALSE);
448             }
449           else
450             {
451               THROW (ReportedBoundsError);
452             }
453           break;
454         case PHS_DSC_ACTION:
455           if (length == 1)
456             {
457               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_dsc_action,
458                                    tvb, pos, length, FALSE);
459             }
460           else
461             {
462               THROW (ReportedBoundsError);
463             }
464           break;
465         case PHS_ERRORS:
466           dissect_phs_err (tvb, phs_tree, pos, length);
467         case PHS_FIELD:
468           proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phsf, tvb, pos,
469                                length, FALSE);
470           break;
471         case PHS_INDEX:
472           if (length == 1)
473             {
474               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phsi, tvb, pos,
475                                    length, FALSE);
476             }
477           else
478             {
479               THROW (ReportedBoundsError);
480             }
481           break;
482         case PHS_MASK:
483           proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phsm, tvb, pos,
484                                length, FALSE);
485           break;
486         case PHS_SUP_SIZE:
487           if (length == 1)
488             {
489               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phss, tvb, pos,
490                                    length, FALSE);
491             }
492           else
493             {
494               THROW (ReportedBoundsError);
495             }
496           break;
497         case PHS_VERIFICATION:
498           if (length == 1)
499             {
500               proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_phsf, tvb, pos,
501                                    length, FALSE);
502             }
503           else
504             {
505               THROW (ReportedBoundsError);
506             }
507           break;
508         case PHS_VENDOR_SPEC:
509           proto_tree_add_item (phs_tree, hf_docsis_tlv_phs_vendorspec, tvb,
510                                pos, length, FALSE);
511           break;
512         }                       /* switch */
513       pos = pos + length;
514
515     }                           /* while */
516 }
517
518
519 static void
520 dissect_reqxmit_policy (tvbuff_t * tvb, proto_tree * tree, int start)
521 {
522   guint32 value;
523   proto_item *it;
524   proto_tree *pol_tree;
525
526   value = tvb_get_ntohl (tvb, start);
527   it =
528     proto_tree_add_item (tree, hf_docsis_tlv_sflow_reqxmit_pol, tvb, start, 4,
529                          FALSE);
530   pol_tree = proto_item_add_subtree (it, ett_docsis_tlv_reqxmitpol);
531
532   if (value & 0x01)
533     proto_tree_add_text (pol_tree, tvb, start, 4,
534                          "Service flow MUST NOT use \"all CMs\" broadcast request opportunities");
535   if (value & 0x02)
536     proto_tree_add_text (pol_tree, tvb, start, 4,
537                          "Service flow MUST NOT use priority multicast request opportunities");
538   if (value & 0x04)
539     proto_tree_add_text (pol_tree, tvb, start, 4,
540                          "Service flow MUST NOT use Request/Data opportunities for requests");
541   if (value & 0x08)
542     proto_tree_add_text (pol_tree, tvb, start, 4,
543                          "Service flow MUST NOT use Request/Data opportunities for data");
544   if (value & 0x10)
545     proto_tree_add_text (pol_tree, tvb, start, 4,
546                          "Service flow MUST NOT use piggy back requests with data");
547   if (value & 0x20)
548     proto_tree_add_text (pol_tree, tvb, start, 4,
549                          "Service flow MUST NOT concatenate data");
550   if (value & 0x40)
551     proto_tree_add_text (pol_tree, tvb, start, 4,
552                          "Service flow MUST NOT fragment data");
553   if (value & 0x80)
554     proto_tree_add_text (pol_tree, tvb, start, 4,
555                          "Service flow MUST NOT suppress payload headers");
556   if (value & 0x100)
557     proto_tree_add_text (pol_tree, tvb, start, 4,
558                          "Service flow MUST drop packets that do not fit in the UGS size");
559 }
560
561 static void
562 dissect_sflow_err (tvbuff_t * tvb, proto_tree * tree, int start,
563                    guint16 len)
564 {
565   guint8 type, length;
566   proto_item *it;
567   proto_tree *err_tree;
568   int pos = start;
569   it =
570     proto_tree_add_text (tree, tvb, start, len,
571                          "5 Service Flow Error Encodings (Length = %u)", len);
572   err_tree = proto_item_add_subtree (it, ett_docsis_tlv_sflow_err);
573
574   while (pos < (start + len))
575     {
576       type = tvb_get_guint8 (tvb, pos++);
577       length = tvb_get_guint8 (tvb, pos++);
578       switch (type)
579         {
580         case SFW_ERR_PARAM:
581           if (length == 1)
582             {
583               proto_tree_add_item (err_tree, hf_docsis_tlv_sflow_err_param,
584                                    tvb, pos, length, FALSE);
585             }
586           else
587             {
588               THROW (ReportedBoundsError);
589             }
590           break;
591         case SFW_ERR_CODE:
592           if (length == 1)
593             {
594               proto_tree_add_item (err_tree, hf_docsis_tlv_sflow_err_code,
595                                    tvb, pos, length, FALSE);
596             }
597           else
598             {
599               THROW (ReportedBoundsError);
600             }
601           break;
602         case SFW_ERR_MSG:
603           proto_tree_add_item (err_tree, hf_docsis_tlv_sflow_err_msg, tvb,
604                                pos, length, FALSE);
605           break;
606         }                       /* switch */
607       pos = pos + length;
608
609     }                           /* while */
610 }
611
612 static void
613 dissect_downstream_sflow (tvbuff_t * tvb, proto_tree * sflow_tree,
614                           int start, guint16 len)
615 {
616   guint8 type, length;
617   int pos = start;
618   while (pos < (start + len))
619     {
620       type = tvb_get_guint8 (tvb, pos++);
621       length = tvb_get_guint8 (tvb, pos++);
622       switch (type)
623         {
624         case SFW_MAX_DOWN_LAT:
625           if (length == 4)
626             {
627               proto_tree_add_item (sflow_tree,
628                                    hf_docsis_tlv_sflow_max_down_latency, tvb,
629                                    pos, length, FALSE);
630             }
631           else
632             {
633               THROW (ReportedBoundsError);
634
635             }
636           break;
637         }                       /* switch */
638       pos = pos + length;
639
640     }                           /* while */
641 }
642
643 static void
644 dissect_upstream_sflow (tvbuff_t * tvb, proto_tree * sflow_tree,
645                         int start, guint16 len)
646 {
647   guint8 type, length;
648   int pos = start;
649   while (pos < (start + len))
650     {
651       type = tvb_get_guint8 (tvb, pos++);
652       length = tvb_get_guint8 (tvb, pos++);
653       switch (type)
654         {
655         case SFW_MAX_CONCAT_BURST:
656           if (length == 2)
657             {
658               proto_tree_add_item (sflow_tree,
659                                    hf_docsis_tlv_sflow_max_concat_burst, tvb,
660                                    pos, length, FALSE);
661             }
662           else
663             {
664               THROW (ReportedBoundsError);
665
666             }
667           break;
668         case SFW_SCHEDULING_TYPE:
669           if (length == 1)
670             {
671               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_sched_type,
672                                    tvb, pos, length, FALSE);
673             }
674           else
675             {
676               THROW (ReportedBoundsError);
677             }
678           break;
679         case SFW_REQ_XMIT_POL:
680           dissect_reqxmit_policy (tvb, sflow_tree, pos);
681           break;
682         case SFW_NOM_POLL_INT:
683           if (length == 4)
684             {
685               proto_tree_add_item (sflow_tree,
686                                    hf_docsis_tlv_sflow_nominal_polling, tvb,
687                                    pos, length, FALSE);
688             }
689           else
690             {
691               THROW (ReportedBoundsError);
692             }
693           break;
694         case SFW_POLL_JTTR_TOL:
695           if (length == 4)
696             {
697               proto_tree_add_item (sflow_tree,
698                                    hf_docsis_tlv_sflow_tolerated_jitter, tvb,
699                                    pos, length, FALSE);
700             }
701           else
702             {
703               THROW (ReportedBoundsError);
704             }
705           break;
706         case SFW_UG_SIZE:
707           if (length == 2)
708             {
709               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_ugs_size,
710                                    tvb, pos, length, FALSE);
711             }
712           else
713             {
714               THROW (ReportedBoundsError);
715             }
716           break;
717         case SFW_NOM_GRNT_INTV:
718           if (length == 4)
719             {
720               proto_tree_add_item (sflow_tree,
721                                    hf_docsis_tlv_sflow_nom_grant_intvl, tvb,
722                                    pos, length, FALSE);
723             }
724           else
725             {
726               THROW (ReportedBoundsError);
727             }
728           break;
729         case SFW_GRNT_JTTR_TOL:
730           if (length == 4)
731             {
732               proto_tree_add_item (sflow_tree,
733                                    hf_docsis_tlv_sflow_tol_grant_jitter, tvb,
734                                    pos, length, FALSE);
735             }
736           else
737             {
738               THROW (ReportedBoundsError);
739             }
740           break;
741         case SFW_GRNTS_PER_INTV:
742           if (length == 1)
743             {
744               proto_tree_add_item (sflow_tree,
745                                    hf_docsis_tlv_sflow_grants_per_intvl, tvb,
746                                    pos, length, FALSE);
747             }
748           else
749             {
750               THROW (ReportedBoundsError);
751             }
752           break;
753         case SFW_IP_TOS_OVERWRITE:
754           if (length == 2)
755             {
756               proto_tree_add_item (sflow_tree,
757                                    hf_docsis_tlv_sflow_ip_tos_overwrite, tvb,
758                                    pos, length, FALSE);
759             }
760           else
761             {
762               THROW (ReportedBoundsError);
763             }
764           break;
765         case SFW_UG_TIME_REF:
766           if (length == 4)
767             {
768               proto_tree_add_item (sflow_tree,
769                                    hf_docsis_tlv_sflow_ugs_timeref, tvb, pos,
770                                    length, FALSE);
771             }
772           else
773             {
774               THROW (ReportedBoundsError);
775             }
776           break;
777
778         }                       /* switch */
779       pos = pos + length;
780
781     }                           /* while */
782 }
783
784 static void
785 dissect_sflow (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len,
786                guint8 direction)
787 {
788   guint8 type, length;
789   proto_item *it;
790   proto_tree *sflow_tree;
791   int pos = start;
792   if (direction == 24)
793     it =
794       proto_tree_add_text (tree, tvb, start, len,
795                            "24 Upstream Service Flow (Length = %u)", len);
796   else if (direction == 25)
797     it =
798       proto_tree_add_text (tree, tvb, start, len,
799                            "25 Downstream Service Flow (Length = %u)", len);
800   else
801     return;
802   sflow_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr);
803
804   while (pos < (start + len))
805     {
806       type = tvb_get_guint8 (tvb, pos++);
807       length = tvb_get_guint8 (tvb, pos++);
808       switch (type)
809         {
810         case SFW_REF:
811           if (length == 2)
812             {
813               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_ref, tvb,
814                                    pos, length, FALSE);
815             }
816           else
817             {
818               THROW (ReportedBoundsError);
819             }
820           break;
821         case SFW_ID:
822           if (length == 4)
823             {
824               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_id, tvb,
825                                    pos, length, FALSE);
826             }
827           else
828             {
829               THROW (ReportedBoundsError);
830             }
831           break;
832         case SFW_SID:
833           if (length == 2)
834             {
835               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_sid, tvb,
836                                    pos, length, FALSE);
837             }
838           else
839             {
840               THROW (ReportedBoundsError);
841             }
842           break;
843         case SFW_SERVICE_CLASS_NAME:
844           proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_classname, tvb,
845                                pos, length, FALSE);
846           break;
847         case SFW_ERRORS:
848           dissect_sflow_err (tvb, sflow_tree, pos, length);
849           break;
850         case SFW_QOS_SET_TYPE:
851           if (length == 1)
852             {
853               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_qos_param,
854                                    tvb, pos, length, FALSE);
855             }
856           else
857             {
858               THROW (ReportedBoundsError);
859             }
860           break;
861         case SFW_TRAF_PRI:
862           if (length == 1)
863             {
864               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_traf_pri,
865                                    tvb, pos, length, FALSE);
866             }
867           else
868             {
869               THROW (ReportedBoundsError);
870             }
871           break;
872         case SFW_MAX_SUSTAINED:
873           if (length == 4)
874             {
875               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_max_sus,
876                                    tvb, pos, length, FALSE);
877             }
878           else
879             {
880               THROW (ReportedBoundsError);
881             }
882           break;
883         case SFW_MAX_BURST:
884           if (length == 4)
885             {
886               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_max_burst,
887                                    tvb, pos, length, FALSE);
888             }
889           else
890             {
891               THROW (ReportedBoundsError);
892             }
893           break;
894         case SFW_MIN_RSVD_TRAF:
895           if (length == 4)
896             {
897               proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_min_traf,
898                                    tvb, pos, length, FALSE);
899             }
900           else
901             {
902               THROW (ReportedBoundsError);
903             }
904           break;
905         case SFW_MIN_RSVD_PACKETSIZE:
906           if (length == 2)
907             {
908               proto_tree_add_item (sflow_tree,
909                                    hf_docsis_tlv_sflow_ass_min_pkt_size, tvb,
910                                    pos, length, FALSE);
911             }
912           else
913             {
914               THROW (ReportedBoundsError);
915             }
916           break;
917         case SFW_ACTIVE_QOS_TIMEOUT:
918           if (length == 2)
919             {
920               proto_tree_add_item (sflow_tree,
921                                    hf_docsis_tlv_sflow_timeout_active, tvb,
922                                    pos, length, FALSE);
923             }
924           else
925             {
926               THROW (ReportedBoundsError);
927             }
928           break;
929         case SFW_ADMITT_QOS_TIMEOUT:
930           if (length == 2)
931             {
932               proto_tree_add_item (sflow_tree,
933                                    hf_docsis_tlv_sflow_timeout_admitted, tvb,
934                                    pos, length, FALSE);
935             }
936           else
937             {
938               THROW (ReportedBoundsError);
939             }
940           break;
941         case SFW_VENDOR_SPEC:
942           proto_tree_add_item (sflow_tree, hf_docsis_tlv_sflow_vendor_spec,
943                                tvb, pos, length, FALSE);
944           break;
945         default:
946           if (direction == 24)
947             dissect_upstream_sflow (tvb, sflow_tree, pos - 2, length);
948           else
949             dissect_downstream_sflow (tvb, sflow_tree, pos - 2, length);
950           break;
951
952         }                       /* switch (type) */
953       pos = pos + length;
954     }                           /* while(pos < start + len) */
955
956 }
957
958 static void
959 dissect_dot1q_clsfr (tvbuff_t * tvb, proto_tree * tree, int start,
960                      guint16 len)
961 {
962   guint8 type, length;
963   proto_item *it;
964   proto_tree *dot1qclsfr_tree;
965   int pos = start;
966   it =
967     proto_tree_add_text (tree, tvb, start, len,
968                          "11 801.1P/Q Classifiers (Length = %u)", len);
969   dot1qclsfr_tree = proto_item_add_subtree (it, ett_docsis_tlv_cos);
970
971   while (pos < (start + len))
972     {
973       type = tvb_get_guint8 (tvb, pos++);
974       length = tvb_get_guint8 (tvb, pos++);
975       switch (type)
976         {
977         case CFR_D1Q_USER_PRI:
978           if (length == 2)
979             {
980               proto_tree_add_item (dot1qclsfr_tree,
981                                    hf_docsis_tlv_dot1qclsfr_user_pri, tvb,
982                                    pos, length, FALSE);
983             }
984           else
985             {
986               THROW (ReportedBoundsError);
987             }
988           break;
989         case CFR_D1Q_VLAN_ID:
990           if (length == 2)
991             {
992               proto_tree_add_item (dot1qclsfr_tree,
993                                    hf_docsis_tlv_dot1qclsfr_vlanid, tvb, pos,
994                                    length, FALSE);
995             }
996           else
997             {
998               THROW (ReportedBoundsError);
999             }
1000           break;
1001         case CFR_D1Q_VENDOR_SPEC:
1002           proto_tree_add_item (dot1qclsfr_tree,
1003                                hf_docsis_tlv_dot1qclsfr_vendorspec, tvb, pos,
1004                                length, FALSE);
1005           break;
1006         }                       /* switch */
1007       pos = pos + length;
1008
1009     }                           /* while */
1010 }
1011
1012 static void
1013 dissect_eth_clsfr (tvbuff_t * tvb, proto_tree * tree, int start,
1014                    guint16 len)
1015 {
1016   guint8 type, length;
1017   proto_item *it;
1018   proto_tree *ethclsfr_tree;
1019   int pos = start;
1020   it =
1021     proto_tree_add_text (tree, tvb, start, len,
1022                          "10 Ethernet Classifiers (Length = %u)", len);
1023   ethclsfr_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr_eth);
1024
1025   while (pos < (start + len))
1026     {
1027       type = tvb_get_guint8 (tvb, pos++);
1028       length = tvb_get_guint8 (tvb, pos++);
1029       switch (type)
1030         {
1031         case CFR_ETH_DST_MAC:
1032           if (length == 6)
1033             {
1034               proto_tree_add_item (ethclsfr_tree, hf_docsis_tlv_ethclsfr_dmac,
1035                                    tvb, pos, length, FALSE);
1036             }
1037           else
1038             {
1039               THROW (ReportedBoundsError);
1040             }
1041           break;
1042         case CFR_ETH_SRC_MAC:
1043           if (length == 6)
1044             {
1045               proto_tree_add_item (ethclsfr_tree, hf_docsis_tlv_ethclsfr_smac,
1046                                    tvb, pos, length, FALSE);
1047             }
1048           else
1049             {
1050               THROW (ReportedBoundsError);
1051             }
1052           break;
1053         case CFR_ETH_DSAP:
1054           if (length == 3)
1055             {
1056               proto_tree_add_item (ethclsfr_tree,
1057                                    hf_docsis_tlv_ethclsfr_ethertype, tvb, pos,
1058                                    length, FALSE);
1059             }
1060           else
1061             {
1062               THROW (ReportedBoundsError);
1063             }
1064           break;
1065         }                       /* switch */
1066       pos = pos + length;
1067
1068     }                           /* while */
1069
1070
1071
1072 }
1073
1074 static void
1075 dissect_clsfr_err (tvbuff_t * tvb, proto_tree * tree, int start,
1076                    guint16 len)
1077 {
1078   guint8 type, length;
1079   proto_item *it;
1080   proto_tree *err_tree;
1081   int pos = start;
1082   it =
1083     proto_tree_add_text (tree, tvb, start, len,
1084                          "8 Classifier Error Encodings (Length = %u)", len);
1085   err_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr_err);
1086
1087   while (pos < (start + len))
1088     {
1089       type = tvb_get_guint8 (tvb, pos++);
1090       length = tvb_get_guint8 (tvb, pos++);
1091       switch (type)
1092         {
1093         case CFR_ERR_PARAM:
1094           if (length == 1)
1095             proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_param, tvb,
1096                                  pos, length, FALSE);
1097           else if (length == 2)
1098             {
1099               proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_param,
1100                                    tvb, pos, 1, FALSE);
1101               proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_param,
1102                                    tvb, pos + 1, 1, FALSE);
1103             }
1104           else
1105             {
1106               THROW (ReportedBoundsError);
1107             }
1108           break;
1109         case CFR_ERR_CODE:
1110           if (length == 1)
1111             {
1112               proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_code,
1113                                    tvb, pos, length, FALSE);
1114             }
1115           else
1116             {
1117               THROW (ReportedBoundsError);
1118             }
1119           break;
1120         case CFR_ERR_MSG:
1121           proto_tree_add_item (err_tree, hf_docsis_tlv_clsfr_err_msg, tvb,
1122                                pos, length, FALSE);
1123           break;
1124         }                       /* switch */
1125       pos = pos + length;
1126
1127     }                           /* while */
1128
1129
1130
1131 }
1132
1133 static void
1134 dissect_ip_classifier (tvbuff_t * tvb, proto_tree * tree, int start,
1135                        guint16 len)
1136 {
1137   guint8 type, length;
1138   proto_item *it;
1139   proto_tree *ipclsfr_tree;
1140   int pos = start;
1141   it =
1142     proto_tree_add_text (tree, tvb, start, len,
1143                          "9 IP Classifier (Length = %u)", len);
1144   ipclsfr_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr_ip);
1145
1146   while (pos < (start + len))
1147     {
1148       type = tvb_get_guint8 (tvb, pos++);
1149       length = tvb_get_guint8 (tvb, pos++);
1150       switch (type)
1151         {
1152         case CFR_IP_TOS_RANGE_MASK:
1153           if (length == 3)
1154             {
1155               proto_tree_add_item (ipclsfr_tree,
1156                                    hf_docsis_tlv_ipclsfr_tosmask, tvb, pos,
1157                                    length, FALSE);
1158             }
1159           else
1160             {
1161               THROW (ReportedBoundsError);
1162             }
1163           break;
1164         case CFR_IP_PROTO:
1165           if (length == 2)
1166             {
1167               proto_tree_add_item (ipclsfr_tree,
1168                                    hf_docsis_tlv_ipclsfr_ipproto, tvb, pos,
1169                                    length, FALSE);
1170             }
1171           else
1172             {
1173               THROW (ReportedBoundsError);
1174             }
1175           break;
1176         case CFR_IP_SOURCE_ADDR:
1177           if (length == 4)
1178             {
1179               proto_tree_add_item (ipclsfr_tree, hf_docsis_tlv_ipclsfr_src,
1180                                    tvb, pos, length, FALSE);
1181             }
1182           else
1183             {
1184               THROW (ReportedBoundsError);
1185             }
1186           break;
1187         case CFR_IP_SOURCE_MASK:
1188           if (length == 4)
1189             {
1190               proto_tree_add_item (ipclsfr_tree,
1191                                    hf_docsis_tlv_ipclsfr_srcmask, tvb, pos,
1192                                    length, FALSE);
1193             }
1194           else
1195             {
1196               THROW (ReportedBoundsError);
1197             }
1198           break;
1199         case CFR_IP_DEST_ADDR:
1200           if (length == 4)
1201             {
1202               proto_tree_add_item (ipclsfr_tree, hf_docsis_tlv_ipclsfr_dst,
1203                                    tvb, pos, length, FALSE);
1204             }
1205           else
1206             {
1207               THROW (ReportedBoundsError);
1208             }
1209           break;
1210         case CFR_IP_DEST_MASK:
1211           if (length == 4)
1212             {
1213               proto_tree_add_item (ipclsfr_tree,
1214                                    hf_docsis_tlv_ipclsfr_dstmask, tvb, pos,
1215                                    length, FALSE);
1216             }
1217           else
1218             {
1219               THROW (ReportedBoundsError);
1220             }
1221           break;
1222         case CFR_IP_SRCPORT_START:
1223           if (length == 2)
1224             {
1225               proto_tree_add_item (ipclsfr_tree,
1226                                    hf_docsis_tlv_ipclsfr_sport_start, tvb,
1227                                    pos, length, FALSE);
1228             }
1229           else
1230             {
1231               THROW (ReportedBoundsError);
1232             }
1233           break;
1234         case CFR_IP_SRCPORT_END:
1235           if (length == 2)
1236             {
1237               proto_tree_add_item (ipclsfr_tree,
1238                                    hf_docsis_tlv_ipclsfr_sport_end, tvb, pos,
1239                                    length, FALSE);
1240             }
1241           else
1242             {
1243               THROW (ReportedBoundsError);
1244             }
1245           break;
1246         case CFR_IP_DSTPORT_START:
1247           if (length == 2)
1248             {
1249               proto_tree_add_item (ipclsfr_tree,
1250                                    hf_docsis_tlv_ipclsfr_dport_start, tvb,
1251                                    pos, length, FALSE);
1252             }
1253           else
1254             {
1255               THROW (ReportedBoundsError);
1256             }
1257           break;
1258         case CFR_IP_DSTPORT_END:
1259           if (length == 2)
1260             {
1261               proto_tree_add_item (ipclsfr_tree,
1262                                    hf_docsis_tlv_ipclsfr_dport_end, tvb, pos,
1263                                    length, FALSE);
1264             }
1265           else
1266             {
1267               THROW (ReportedBoundsError);
1268             }
1269           break;
1270         }                       /* switch */
1271       pos = pos + length;
1272
1273     }                           /* while */
1274
1275 }
1276 static void
1277 dissect_classifiers (tvbuff_t * tvb, proto_tree * tree, int start,
1278                      guint16 len, guint8 direction)
1279 {
1280   guint8 type, length;
1281   proto_item *it;
1282   proto_tree *clsfr_tree;
1283   int pos = start;
1284   if (direction == 22)
1285     it =
1286       proto_tree_add_text (tree, tvb, start, len,
1287                            "22 Upstream Packet Classifier (Length = %u)",
1288                            len);
1289   else if (direction == 23)
1290     it =
1291       proto_tree_add_text (tree, tvb, start, len,
1292                            "23 Downstream Packet Classifier (Length = %u)",
1293                            len);
1294   else
1295     return;
1296   clsfr_tree = proto_item_add_subtree (it, ett_docsis_tlv_clsfr);
1297
1298   while (pos < (start + len))
1299     {
1300       type = tvb_get_guint8 (tvb, pos++);
1301       length = tvb_get_guint8 (tvb, pos++);
1302       switch (type)
1303         {
1304         case CFR_REF:
1305           if (length == 1)
1306             {
1307               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_ref, tvb,
1308                                    pos, length, FALSE);
1309             }
1310           else
1311             {
1312               THROW (ReportedBoundsError);
1313             }
1314           break;
1315         case CFR_ID:
1316           if (length == 2)
1317             {
1318               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_id, tvb,
1319                                    pos, length, FALSE);
1320             }
1321           else
1322             {
1323               THROW (ReportedBoundsError);
1324             }
1325           break;
1326         case CFR_SFLOW_REF:
1327           if (length == 2)
1328             {
1329               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_sflow_ref,
1330                                    tvb, pos, length, FALSE);
1331             }
1332           else
1333             {
1334               THROW (ReportedBoundsError);
1335             }
1336           break;
1337         case CFR_SFLOW_ID:
1338           if (length == 4)
1339             {
1340               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_sflow_id,
1341                                    tvb, pos, length, FALSE);
1342             }
1343           else
1344             {
1345               THROW (ReportedBoundsError);
1346             }
1347           break;
1348         case CFR_RULE_PRI:
1349           if (length == 1)
1350             {
1351               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_rule_pri,
1352                                    tvb, pos, length, FALSE);
1353             }
1354           else
1355             {
1356               THROW (ReportedBoundsError);
1357             }
1358           break;
1359         case CFR_ACT_STATE:
1360           if (length == 1)
1361             {
1362               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_act_state,
1363                                    tvb, pos, length, FALSE);
1364             }
1365           else
1366             {
1367               THROW (ReportedBoundsError);
1368             }
1369           break;
1370         case CFR_DSA_ACTION:
1371           if (length == 1)
1372             {
1373               proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_dsc_act,
1374                                    tvb, pos, length, FALSE);
1375             }
1376           else
1377             {
1378               THROW (ReportedBoundsError);
1379             }
1380           break;
1381         case CFR_ERROR:
1382           dissect_clsfr_err (tvb, clsfr_tree, pos, length);
1383           break;
1384         case CFR_IP_CLASSIFIER:
1385           dissect_ip_classifier (tvb, clsfr_tree, pos, length);
1386           break;
1387         case CFR_ETH_CLASSIFIER:
1388           dissect_eth_clsfr (tvb, clsfr_tree, pos, length);
1389           break;
1390         case CFR_8021Q_CLASSIFIER:
1391           dissect_dot1q_clsfr (tvb, clsfr_tree, pos, length);
1392           break;
1393         case CFR_VENDOR_SPEC:
1394           proto_tree_add_item (clsfr_tree, hf_docsis_tlv_clsfr_vendor_spc,
1395                                tvb, pos, length, FALSE);
1396           break;
1397         }                       /* switch */
1398       pos = pos + length;
1399
1400     }                           /* while */
1401
1402
1403
1404 }
1405
1406 static void
1407 dissect_doc10cos (tvbuff_t * tvb, proto_tree * tree, int start,
1408                   guint16 len)
1409 {
1410   guint8 type, length;
1411   proto_item *it;
1412   proto_tree *doc10cos_tree;
1413   int pos = start;
1414   it =
1415     proto_tree_add_text (tree, tvb, start, len,
1416                          "1 Docsis 1.0 Class of Service (Length = %u)", len);
1417   doc10cos_tree = proto_item_add_subtree (it, ett_docsis_tlv_cos);
1418
1419   while (pos < (start + len))
1420     {
1421       type = tvb_get_guint8 (tvb, pos++);
1422       length = tvb_get_guint8 (tvb, pos++);
1423       switch (type)
1424         {
1425         case 1:
1426           if (length == 1)
1427             {
1428               proto_tree_add_item (doc10cos_tree, hf_docsis_tlv_cos_id, tvb,
1429                                    pos, length, FALSE);
1430             }
1431           else
1432             {
1433               THROW (ReportedBoundsError);
1434             }
1435           break;
1436         case 2:
1437           if (length == 2)
1438             {
1439               proto_tree_add_item (doc10cos_tree, hf_docsis_tlv_cos_sid, tvb,
1440                                    pos, length, FALSE);
1441             }
1442           else
1443             {
1444               THROW (ReportedBoundsError);
1445             }
1446           break;
1447         }                       /* switch */
1448       pos = pos + length;
1449
1450     }                           /* while */
1451 }
1452
1453 static void
1454 dissect_modemcap (tvbuff_t * tvb, proto_tree * tree, int start,
1455                   guint16 len)
1456 {
1457   guint8 type, length;
1458   proto_item *it;
1459   proto_tree *mcap_tree;
1460   int pos = start;
1461
1462   it =
1463     proto_tree_add_text (tree, tvb, start, len,
1464                          "5 Modem Capabilities Type (Length = %u)", len);
1465
1466   mcap_tree = proto_item_add_subtree (it, ett_docsis_tlv_mcap);
1467   while (pos < (start + len))
1468     {
1469       type = tvb_get_guint8 (tvb, pos++);
1470       length = tvb_get_guint8 (tvb, pos++);
1471       switch (type)
1472         {
1473         case CAP_CONCAT:
1474           if (length == 1)
1475             {
1476               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_concat, tvb,
1477                                    pos, length, FALSE);
1478             }
1479           else
1480             {
1481               THROW (ReportedBoundsError);
1482             }
1483           break;
1484         case CAP_DOCSIS_VER:
1485           if (length == 1)
1486             {
1487               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_docs_ver,
1488                                    tvb, pos, length, FALSE);
1489             }
1490           else
1491             {
1492               THROW (ReportedBoundsError);
1493             }
1494           break;
1495         case CAP_FRAG:
1496           if (length == 1)
1497             {
1498               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_frag, tvb,
1499                                    pos, length, FALSE);
1500             }
1501           else
1502             {
1503               THROW (ReportedBoundsError);
1504             }
1505           break;
1506         case CAP_PHS:
1507           if (length == 1)
1508             {
1509               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_phs, tvb,
1510                                    pos, length, FALSE);
1511             }
1512           else
1513             {
1514               THROW (ReportedBoundsError);
1515             }
1516           break;
1517         case CAP_IGMP:
1518           if (length == 1)
1519             {
1520               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_igmp, tvb,
1521                                    pos, length, FALSE);
1522             }
1523           else
1524             {
1525               THROW (ReportedBoundsError);
1526             }
1527           break;
1528         case CAP_PRIVACY:
1529           if (length == 1)
1530             {
1531               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_privacy, tvb,
1532                                    pos, length, FALSE);
1533             }
1534           else
1535             {
1536               THROW (ReportedBoundsError);
1537             }
1538           break;
1539         case CAP_DOWN_SAID:
1540           if (length == 1)
1541             {
1542               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_down_said,
1543                                    tvb, pos, length, FALSE);
1544             }
1545           else
1546             {
1547               THROW (ReportedBoundsError);
1548             }
1549           break;
1550         case CAP_UP_SID:
1551           if (length == 1)
1552             {
1553               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_up_sid, tvb,
1554                                    pos, length, FALSE);
1555             }
1556           else
1557             {
1558               THROW (ReportedBoundsError);
1559             }
1560           break;
1561         case CAP_OPT_FILT:
1562           if (length == 1)
1563             {
1564               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_8021P_filter,
1565                                    tvb, pos, length, FALSE);
1566               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_8021Q_filter,
1567                                    tvb, pos, length, FALSE);
1568             }
1569           else
1570             {
1571               THROW (ReportedBoundsError);
1572             }
1573           break;
1574         case CAP_XMIT_EQPERSYM:
1575           if (length == 1)
1576             {
1577               proto_tree_add_item (mcap_tree,
1578                                    hf_docsis_tlv_mcap_xmit_eq_taps_per_sym,
1579                                    tvb, pos, length, FALSE);
1580             }
1581           else
1582             {
1583               THROW (ReportedBoundsError);
1584             }
1585           break;
1586         case CAP_NUM_XMIT_EQ_TAPS:
1587           if (length == 1)
1588             {
1589               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_xmit_eq_taps,
1590                                    tvb, pos, length, FALSE);
1591             }
1592           else
1593             {
1594               THROW (ReportedBoundsError);
1595             }
1596           break;
1597         case CAP_DCC:
1598           if (length == 1)
1599             {
1600               proto_tree_add_item (mcap_tree, hf_docsis_tlv_mcap_dcc, tvb,
1601                                    pos, length, FALSE);
1602             }
1603           else
1604             {
1605               THROW (ReportedBoundsError);
1606             }
1607           break;
1608         }                       /* switch (type) */
1609       pos = pos + length;
1610     }                           /* while (pos < pos+len) */
1611
1612 }
1613
1614 static void
1615 dissect_cos (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
1616 {
1617   guint8 type, length;
1618   proto_item *it;
1619   proto_tree *cos_tree;
1620   int pos = start;
1621
1622   it =
1623     proto_tree_add_text (tree, tvb, start, len,
1624                          "4 Class of Service Type (Length = %u)", len);
1625   cos_tree = proto_item_add_subtree (it, ett_docsis_tlv_cos);
1626
1627   while (pos < (start + len))
1628     {
1629       type = tvb_get_guint8 (tvb, pos++);
1630       length = tvb_get_guint8 (tvb, pos++);
1631       switch (type)
1632         {
1633         case COS_CLASSID:
1634           if (length == 1)
1635             {
1636               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_id, tvb, pos,
1637                                    length, FALSE);
1638             }
1639           else
1640             {
1641               THROW (ReportedBoundsError);
1642             }
1643           break;
1644         case COS_MAX_DOWN:
1645           if (length == 4)
1646             {
1647               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_max_down, tvb,
1648                                    pos, length, FALSE);
1649             }
1650           else
1651             {
1652               THROW (ReportedBoundsError);
1653             }
1654           break;
1655         case COS_MAX_UP:
1656           if (length == 4)
1657             {
1658               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_max_up, tvb,
1659                                    pos, length, FALSE);
1660             }
1661           else
1662             {
1663               THROW (ReportedBoundsError);
1664             }
1665           break;
1666         case COS_UP_CH_PRIO:
1667           if (length == 1)
1668             {
1669               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_up_chnl_pri,
1670                                    tvb, pos, length, FALSE);
1671             }
1672           else
1673             {
1674               THROW (ReportedBoundsError);
1675             }
1676           break;
1677         case COS_MIN_UP_RATE:
1678           if (length == 4)
1679             {
1680               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_min_grntd_up,
1681                                    tvb, pos, length, FALSE);
1682             }
1683           else
1684             {
1685               THROW (ReportedBoundsError);
1686             }
1687           break;
1688         case COS_MAX_UP_BURST:
1689           if (length == 2)
1690             {
1691               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_max_up_burst,
1692                                    tvb, pos, length, FALSE);
1693             }
1694           else
1695             {
1696               THROW (ReportedBoundsError);
1697             }
1698           break;
1699         case COS_BP_ENABLE:
1700           if (length == 1)
1701             {
1702               proto_tree_add_item (cos_tree, hf_docsis_tlv_cos_privacy_enable,
1703                                    tvb, pos, length, FALSE);
1704             }
1705           else
1706             {
1707               THROW (ReportedBoundsError);
1708
1709             }
1710           break;
1711         }                       /* switch (type) */
1712       pos = pos + length;
1713     }                           /* while (pos < pos+len) */
1714
1715 }
1716
1717 static void
1718 dissect_svc_unavail(tvbuff_t * tvb, proto_tree * tree, int pos, guint16 length) {
1719
1720   proto_item *svc_unavail_it;
1721   proto_tree *svc_unavail_tree;
1722   svc_unavail_it = proto_tree_add_item (tree,
1723                             hf_docsis_tlv_svc_unavail,
1724                             tvb, pos, length, FALSE);
1725   svc_unavail_tree = proto_item_add_subtree(svc_unavail_it, ett_docsis_tlv_svc_unavail );
1726   proto_tree_add_item (svc_unavail_tree,
1727                        hf_docsis_tlv_svc_unavail_classid, tvb,
1728                         pos, 1, FALSE);
1729   proto_tree_add_item (svc_unavail_tree,
1730                    hf_docsis_tlv_svc_unavail_type, tvb,
1731                    pos+1, 1, FALSE);
1732   proto_tree_add_item (svc_unavail_tree,
1733                    hf_docsis_tlv_svc_unavail_code, tvb,
1734                    pos+2, 1, FALSE);
1735
1736 }
1737
1738 static void
1739 dissect_snmpv3_kickstart(tvbuff_t * tvb, proto_tree *tree, int start, guint16 len) {
1740   proto_item *snmpv3_it;
1741   proto_tree *snmpv3_tree;
1742   guint8 type, length;
1743   int pos = start;
1744
1745   snmpv3_it = proto_tree_add_item (tree,
1746                             hf_docsis_tlv_snmpv3_kick,
1747                             tvb, start, len, FALSE);
1748   snmpv3_tree = proto_item_add_subtree(snmpv3_it, ett_docsis_tlv_snmpv3_kick);
1749
1750   while (pos < (start + len)) {
1751     type = tvb_get_guint8 (tvb, pos++);
1752     length = tvb_get_guint8 (tvb, pos++);
1753     switch (type) {
1754         case SNMPV3_SEC_NAME:
1755           proto_tree_add_item (snmpv3_tree,
1756                    hf_docsis_tlv_snmpv3_kick_name, tvb,
1757                    pos, length, FALSE);
1758           break;
1759         case SNMPV3_MGR_PUB_NUM:
1760           proto_tree_add_item (snmpv3_tree,
1761                    hf_docsis_tlv_snmpv3_kick_publicnum, tvb,
1762                    pos, length, FALSE);
1763           break;
1764     }  /* switch */
1765     pos += length;
1766   }   /* while */
1767 }
1768
1769 static void
1770 dissect_tlv (tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree)
1771 {
1772
1773   proto_item *it;
1774   proto_tree *tlv_tree;
1775   int pos = 0;
1776   gint total_len;
1777   guint8 type, length;
1778   guint16 x;
1779   tvbuff_t *vsif_tvb;
1780
1781   total_len = tvb_reported_length_remaining (tvb, 0);
1782
1783     {
1784       it =
1785         proto_tree_add_protocol_format (tree, proto_docsis_tlv, tvb, 0,
1786                                         total_len, "TLV Data");
1787       tlv_tree = proto_item_add_subtree (it, ett_docsis_tlv);
1788       while (pos < total_len)
1789         {
1790           type = tvb_get_guint8 (tvb, pos++);
1791           length = tvb_get_guint8 (tvb, pos++);
1792           switch (type)
1793             {
1794             case TLV_DOWN_FREQ:
1795               /* This is ugly.  There are multiple type 1 TLV's that may appear
1796                * in the TLV data, the problem is that they are dependent on
1797                * message type.  */
1798               if (length == 4)
1799                 proto_tree_add_item (tlv_tree, hf_docsis_tlv_down_freq, tvb,
1800                                      pos, length, FALSE);
1801               else if (length == 1)
1802                 proto_tree_add_item (tlv_tree, hf_docsis_tlv_rng_tech, tvb,
1803                                      pos, length, FALSE);
1804               else
1805                 dissect_doc10cos (tvb, tlv_tree, pos, length);
1806               break;
1807             case TLV_CHNL_ID:
1808               if (length == 1)
1809                 {
1810                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_upstream_chid,
1811                                        tvb, pos, length, FALSE);
1812                 }
1813               else
1814                 {
1815                   THROW (ReportedBoundsError);
1816                 }
1817               break;
1818             case TLV_NET_ACCESS:
1819               if (length == 1)
1820                 {
1821                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_net_access,
1822                                        tvb, pos, length, FALSE);
1823                 }
1824               else
1825                 {
1826                   THROW (ReportedBoundsError);
1827                 }
1828               break;
1829             case TLV_COS:
1830               dissect_cos (tvb, tlv_tree, pos, length);
1831               break;
1832             case TLV_MODEM_CAP:
1833               dissect_modemcap (tvb, tlv_tree, pos, length);
1834               break;
1835             case TLV_CM_MIC:
1836               if (length == 16)
1837                 {
1838                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_cm_mic, tvb,
1839                                        pos, length, FALSE);
1840                 }
1841               else
1842                 {
1843                   THROW (ReportedBoundsError);
1844                 }
1845               break;
1846             case TLV_CMTS_MIC:
1847               if (length == 16)
1848                 {
1849                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_cmts_mic, tvb,
1850                                        pos, length, FALSE);
1851                 }
1852               else
1853                 {
1854                   THROW (ReportedBoundsError);
1855                 }
1856               break;
1857             case TLV_VENDOR_ID:
1858               if (length == 3)
1859                 {
1860                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_vendor_id, tvb,
1861                                        pos, length, FALSE);
1862                 }
1863               else
1864                 {
1865                   THROW (ReportedBoundsError);
1866                 }
1867               break;
1868             case TLV_SW_UPG_FILE:
1869               proto_tree_add_item (tlv_tree, hf_docsis_tlv_sw_file, tvb, pos,
1870                                    length, FALSE);
1871               break;
1872             case TLV_SNMP_WRITE_CTRL:
1873               proto_tree_add_item (tlv_tree, hf_docsis_tlv_snmp_access, tvb,
1874                                   pos, length, FALSE);
1875               break;
1876             case TLV_SNMP_OBJECT:
1877               proto_tree_add_item (tlv_tree, hf_docsis_tlv_snmp_obj, tvb,
1878                                   pos, length, FALSE);
1879               break;
1880             case TLV_MODEM_IP:
1881               if (length == 4)
1882                 {
1883                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_modem_addr,
1884                                        tvb, pos, length, FALSE);
1885                 }
1886               else
1887                 {
1888                   THROW (ReportedBoundsError);
1889                 }
1890               break;
1891             case TLV_SVC_UNAVAIL:
1892               if (length == 3)
1893                 {
1894                   dissect_svc_unavail(tvb, tlv_tree, pos, length);
1895                 }
1896               else
1897                 {
1898                   THROW (ReportedBoundsError);
1899                 }
1900               break;
1901             case TLV_ETHERNET_MAC:
1902               if (length == 6)
1903                 {
1904                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_cpe_ethernet,
1905                                        tvb, pos, length, FALSE);
1906                 }
1907               else
1908                 {
1909                   THROW (ReportedBoundsError);
1910                 }
1911               break;
1912             case TLV_TEL_SETTINGS:
1913               break;
1914             case TLV_BPI_CONFIG:
1915               proto_tree_add_item (tlv_tree, hf_docsis_tlv_bpi, tvb,
1916                                    pos, length, FALSE);
1917               break;
1918             case TLV_MAX_CPES:
1919               if (length == 1)
1920                 {
1921                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_max_cpe, tvb,
1922                                        pos, length, FALSE);
1923                 }
1924               else
1925                 {
1926                   THROW (ReportedBoundsError);
1927                 }
1928               break;
1929             case TLV_TFTP_TIME:
1930               if (length == 4)
1931                 {
1932                   proto_tree_add_item (tlv_tree,
1933                                        hf_docsis_tlv_tftp_server_timestamp,
1934                                        tvb, pos, length, FALSE);
1935                 }
1936               else
1937                 {
1938                   THROW (ReportedBoundsError);
1939                 }
1940               break;
1941             case TLV_TFTP_MODEM_ADDRESS:
1942               if (length == 4)
1943                 {
1944                   proto_tree_add_item (tlv_tree,
1945                                        hf_docsis_tlv_tftp_prov_modem_address,
1946                                        tvb, pos, length, FALSE);
1947                 }
1948               else
1949                 {
1950                   THROW (ReportedBoundsError);
1951                 }
1952               break;
1953             case TLV_SW_UPG_SRVR:
1954               if (length == 4)
1955                 {
1956                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_sw_upg_srvr,
1957                                        tvb, pos, length, FALSE);
1958                 }
1959               else
1960                 {
1961                   THROW (ReportedBoundsError);
1962                 }
1963               break;
1964             case TLV_UPSTREAM_CLASSIFIER:
1965             case TLV_DOWN_CLASSIFIER:
1966               dissect_classifiers (tvb, tlv_tree, pos, length, type);
1967               break;
1968             case TLV_UPSTREAM_SERVICE_FLOW:
1969             case TLV_DOWN_SERVICE_FLOW:
1970               dissect_sflow (tvb, tlv_tree, pos, length, type);
1971               break;
1972             case TLV_PHS:
1973               dissect_phs (tvb, tlv_tree, pos, length);
1974               break;
1975             case TLV_HMAC_DIGEST:
1976               if (length == 20)
1977                 {
1978                   proto_tree_add_item (tlv_tree,
1979                                       hf_docsis_tlv_hmac_digest, tvb,
1980                                       pos, length, FALSE);
1981                 }
1982               else
1983                 {
1984                   THROW (ReportedBoundsError);
1985                 }
1986               break;
1987             case TLV_MAX_CLASSIFIERS:
1988               if (length == 2)
1989                 {
1990                   proto_tree_add_item (tlv_tree,
1991                                        hf_docsis_tlv_max_classifiers, tvb,
1992                                        pos, length, FALSE);
1993                 }
1994               else
1995                 {
1996                   THROW (ReportedBoundsError);
1997                 }
1998               break;
1999             case TLV_PRIVACY_ENABLE:
2000               if (length == 1)
2001                 {
2002                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_privacy_enable,
2003                                        tvb, pos, length, FALSE);
2004                 }
2005               else
2006                 {
2007                   THROW (ReportedBoundsError);
2008                 }
2009               break;
2010             case TLV_AUTH_BLOCK:
2011               proto_tree_add_item (tlv_tree, hf_docsis_tlv_auth_block,
2012                                    tvb, pos, length, FALSE);
2013               break;
2014             case TLV_KEY_SEQ_NUM:
2015               if (length == 1)
2016                 {
2017                   proto_tree_add_item (tlv_tree, hf_docsis_tlv_key_seq_num, tvb,
2018                                        pos, length, FALSE);
2019                 }
2020               else
2021                 {
2022                   THROW (ReportedBoundsError);
2023                 }
2024               break;
2025             case TLV_MFGR_CVC:
2026               proto_tree_add_item (tlv_tree, hf_docsis_tlv_mfgr_cvc,
2027                                    tvb, pos, length, FALSE);
2028               break;
2029             case TLV_COSIGN_CVC:
2030               proto_tree_add_item (tlv_tree, hf_docsis_tlv_cosign_cvc,
2031                                    tvb, pos, length, FALSE);
2032               break;
2033             case TLV_SNMPV3_KICKSTART:
2034               dissect_snmpv3_kickstart(tvb, tlv_tree, pos, length);
2035               break;
2036             case TLV_SUBS_MGMT_CTRL:
2037               proto_tree_add_item (tlv_tree, hf_docsis_tlv_subs_mgmt_ctrl,
2038                                    tvb, pos, length, FALSE);
2039               break;
2040             case TLV_SUBS_MGMT_CPE:
2041               if ((length % 4) == 0)
2042                 {
2043                 proto_tree_add_item (tlv_tree, hf_docsis_tlv_subs_mgmt_ip_table,
2044                                    tvb, pos, length, FALSE);
2045                 for (x = 0; x < length; x+=4)
2046                   {
2047                   proto_tree_add_item (tlv_tree,
2048                                        hf_docsis_tlv_subs_mgmt_ip_entry,
2049                                        tvb, pos + x, 4, FALSE);
2050                   }
2051                 }
2052               else
2053                 {
2054                   THROW (ReportedBoundsError);
2055                 }
2056               break;
2057             case TLV_SUBS_MGMT_FLTR:
2058               proto_tree_add_item (tlv_tree,
2059                                    hf_docsis_tlv_subs_mgmt_filter_grps,
2060                                    tvb, pos, length, FALSE);
2061               break;
2062             case TLV_VENDOR_SPEC:
2063               vsif_tvb = tvb_new_subset (tvb, pos, length, length);
2064               call_dissector (docsis_vsif_handle, vsif_tvb, pinfo, tlv_tree);
2065               break;
2066             case TLV_END:
2067               break;
2068             }                   /* switch(type) */
2069
2070           pos = pos + length;
2071         }                       /* while (pos < total_len) */
2072     }                           /*if (tree) */
2073
2074
2075
2076 }
2077
2078
2079
2080
2081 /* Register the protocol with Wireshark */
2082
2083 /* this format is require because a script is used to build the C function
2084    that calls all the protocol registration.
2085 */
2086
2087
2088 void
2089 proto_register_docsis_tlv (void)
2090 {
2091
2092 /* Setup list of header fields  See Section 1.6.1 for details*/
2093   static hf_register_info hf[] = {
2094     {&hf_docsis_tlv,
2095      {"TLV Data", "docsis_tlv",
2096       FT_BYTES, BASE_NONE, NULL, 0x0,
2097       NULL, HFILL}
2098      },
2099     {&hf_docsis_tlv_down_freq,
2100      {"1 Downstream Frequency", "docsis_tlv.downfreq",
2101       FT_UINT32, BASE_DEC, NULL, 0x0,
2102       "Downstream Frequency", HFILL}
2103      },
2104     {&hf_docsis_tlv_upstream_chid,
2105      {"2 Upstream Channel ID", "docsis_tlv.upchid",
2106       FT_UINT8, BASE_DEC, NULL, 0x0,
2107       "Service Identifier", HFILL}
2108      },
2109     {&hf_docsis_tlv_net_access,
2110      {"3 Network Access", "docsis_tlv.netaccess",
2111       FT_BOOLEAN, BASE_NONE, TFS (&on_off_tfs), 0x0,
2112       "Network Access TLV", HFILL}
2113      },
2114     {&hf_docsis_tlv_cos,
2115      {"4 COS Encodings", "docsis_tlv.cos",
2116       FT_BYTES, BASE_NONE, NULL, 0x0,
2117       NULL, HFILL}
2118      },
2119     {&hf_docsis_tlv_cos_id,
2120      {".1 Class ID", "docsis_tlv.cos.id",
2121       FT_UINT8, BASE_DEC, NULL, 0x0,
2122       "Class ID", HFILL}
2123      },
2124     {&hf_docsis_tlv_cos_sid,
2125      {".2 Service ID", "docsis_tlv.cos.sid",
2126       FT_UINT16, BASE_DEC, NULL, 0x0,
2127       "Service ID", HFILL}
2128      },
2129     {&hf_docsis_tlv_cos_max_down,
2130      {".2 Max Downstream Rate (bps)", "docsis_tlv.cos.maxdown",
2131       FT_UINT32, BASE_DEC, NULL, 0x0,
2132       "Max Downstream Rate", HFILL}
2133      },
2134     {&hf_docsis_tlv_cos_max_up,
2135      {".3 Max Upstream Rate (bps)", "docsis_tlv.cos.maxup",
2136       FT_UINT32, BASE_DEC, NULL, 0x0,
2137       "Max Upstream Rate", HFILL}
2138      },
2139     {&hf_docsis_tlv_cos_up_chnl_pri,
2140      {".4 Upstream Channel Priority", "docsis_tlv.cos.upchnlpri",
2141       FT_UINT8, BASE_DEC, NULL, 0x0,
2142       "Upstream Channel Priority", HFILL}
2143      },
2144     {&hf_docsis_tlv_cos_min_grntd_up,
2145      {".5 Guaranteed Upstream Rate", "docsis_tlv.cos.mingrntdup",
2146       FT_UINT32, BASE_DEC, NULL, 0x0,
2147       "Guaranteed Minimum Upstream Data Rate", HFILL}
2148      },
2149     {&hf_docsis_tlv_cos_max_up_burst,
2150      {".6 Maximum Upstream Burst", "docsis_tlv.cos.maxupburst",
2151       FT_UINT16, BASE_DEC, NULL, 0x0,
2152       "Maximum Upstream Burst", HFILL}
2153      },
2154     {&hf_docsis_tlv_cos_privacy_enable,
2155      {".7 COS Privacy Enable", "docsis_tlv.cos.privacy_enable",
2156       FT_BOOLEAN, BASE_NONE, TFS (&ena_dis_tfs), 0x0,
2157       "Class of Service Privacy Enable", HFILL}
2158      },
2159     {&hf_docsis_tlv_mcap,
2160      {"5 Modem Capabilities", "docsis_tlv.mcap",
2161       FT_BYTES, BASE_NONE, NULL, 0x0,
2162       "Modem Capabilities", HFILL}
2163      },
2164     {&hf_docsis_tlv_mcap_concat,
2165      {".1 Concatenation Support", "docsis_tlv.mcap.concat",
2166       FT_BOOLEAN, BASE_NONE, TFS (&on_off_tfs), 0x0,
2167       "Concatenation Support", HFILL}
2168      },
2169     {&hf_docsis_tlv_mcap_docs_ver,
2170      {".2 Docsis Version", "docsis_tlv.map.docsver",
2171       FT_UINT8, BASE_DEC, VALS (docs_ver_vals), 0x0,
2172       "DOCSIS Version", HFILL}
2173      },
2174     {&hf_docsis_tlv_mcap_frag,
2175      {".3 Fragmentation Support", "docsis_tlv.mcap.frag",
2176       FT_BOOLEAN, BASE_NONE, TFS (&on_off_tfs), 0x0,
2177       "Fragmentation Support", HFILL}
2178      },
2179     {&hf_docsis_tlv_mcap_phs,
2180      {".4 PHS Support", "docsis_tlv.mcap.phs",
2181       FT_BOOLEAN, BASE_NONE, TFS (&on_off_tfs), 0x0,
2182       "PHS Support", HFILL}
2183      },
2184     {&hf_docsis_tlv_mcap_igmp,
2185      {".5 IGMP Support", "docsis_tlv.mcap.igmp",
2186       FT_BOOLEAN, BASE_NONE, TFS (&on_off_tfs), 0x0,
2187       "IGMP Support", HFILL}
2188      },
2189     {&hf_docsis_tlv_mcap_privacy,
2190      {".6 Privacy Support", "docsis_tlv.mcap.privacy",
2191       FT_BOOLEAN, BASE_NONE, TFS (&on_off_tfs), 0x0,
2192       "Privacy Support", HFILL}
2193      },
2194     {&hf_docsis_tlv_mcap_down_said,
2195      {".7 # Downstream SAIDs Supported", "docsis_tlv.mcap.downsaid",
2196       FT_UINT8, BASE_DEC, NULL, 0x0,
2197       "Downstream Said Support", HFILL}
2198      },
2199     {&hf_docsis_tlv_mcap_up_sid,
2200      {".8 # Upstream SAIDs Supported", "docsis_tlv.mcap.upsid",
2201       FT_UINT8, BASE_DEC, NULL, 0x0,
2202       "Upstream SID Support", HFILL}
2203      },
2204     {&hf_docsis_tlv_mcap_8021P_filter,
2205      {".9 802.1P Filtering Support", "docsis_tlv.mcap.dot1pfiltering",
2206       FT_UINT8, BASE_DEC, VALS (on_off_vals), 0x80,
2207       "802.1P Filtering Support", HFILL}
2208      },
2209     {&hf_docsis_tlv_mcap_8021Q_filter,
2210      {".9 802.1Q Filtering Support", "docsis_tlv.mcap.dot1qfilt",
2211       FT_UINT8, BASE_DEC, VALS (on_off_vals), 0x40,
2212       "802.1Q Filtering Support", HFILL}
2213      },
2214     {&hf_docsis_tlv_mcap_xmit_eq_taps_per_sym,
2215      {".10 Xmit Equalizer Taps/Sym", "docsis_tlv.mcap.tapspersym",
2216       FT_UINT8, BASE_DEC, NULL, 0x0,
2217       "Transmit Equalizer Taps per Symbol", HFILL}
2218      },
2219     {&hf_docsis_tlv_mcap_xmit_eq_taps,
2220      {".11 # Xmit Equalizer Taps", "docsis_tlv.mcap.numtaps",
2221       FT_UINT8, BASE_DEC, NULL, 0x0,
2222       "Number of Transmit Equalizer Taps", HFILL}
2223      },
2224     {&hf_docsis_tlv_mcap_dcc,
2225      {".12 DCC Support", "docsis_tlv.mcap.dcc",
2226       FT_BOOLEAN, BASE_NONE, TFS (&on_off_tfs), 0x0,
2227       "DCC Support", HFILL}
2228      },
2229     {&hf_docsis_tlv_cm_mic,
2230      {"6 CM MIC", "docsis_tlv.cmmic",
2231       FT_BYTES, BASE_NONE, NULL, 0x0,
2232       "Cable Modem Message Integrity Check", HFILL}
2233      },
2234     {&hf_docsis_tlv_cmts_mic,
2235      {"7 CMTS MIC", "docsis_tlv.cmtsmic",
2236       FT_BYTES, BASE_NONE, NULL, 0x0,
2237       "CMTS Message Integrity Check", HFILL}
2238      },
2239     {&hf_docsis_tlv_vendor_id,
2240      {"8 Vendor ID", "docsis_tlv.vendorid",
2241       FT_BYTES, BASE_NONE, NULL, 0x0,
2242       "Vendor Identifier", HFILL}
2243      },
2244     {&hf_docsis_tlv_sw_file,
2245      {"9 Software Upgrade File", "docsis_tlv.sw_upg_file",
2246       FT_STRINGZ, BASE_NONE, NULL, 0x0,
2247       "Software Upgrade File", HFILL}
2248      },
2249     {&hf_docsis_tlv_snmp_access,
2250      {"10 SNMP Write Access", "docsis_tlv.snmp_access",
2251       FT_BYTES, BASE_NONE, NULL, 0x0,
2252       "SNMP Write Access", HFILL}
2253      },
2254     {&hf_docsis_tlv_snmp_obj,
2255      {"11 SNMP Object", "docsis_tlv.snmp_obj",
2256       FT_BYTES, BASE_NONE, NULL, 0x0,
2257       "SNMP Object", HFILL}
2258      },
2259     {&hf_docsis_tlv_modem_addr,
2260      {"12 Modem IP Address", "docsis_tlv.modemaddr",
2261       FT_IPv4, BASE_NONE, NULL, 0x0,
2262       "Modem IP Address", HFILL}
2263      },
2264     {&hf_docsis_tlv_svc_unavail,
2265      {"13 Service Not Available Response", "docsis_tlv.svcunavail",
2266       FT_BYTES, BASE_NONE, NULL, 0x0,
2267       "Service Not Available Response", HFILL}
2268      },
2269     {&hf_docsis_tlv_svc_unavail_classid,
2270      {"Service Not Available: (Class ID)", "docsis_tlv.svcunavail.classid",
2271       FT_UINT8, BASE_DEC, NULL, 0x0,
2272       "Service Not Available (Class ID)", HFILL}
2273      },
2274     {&hf_docsis_tlv_svc_unavail_type,
2275      {"Service Not Available (Type)", "docsis_tlv.svcunavail.type",
2276       FT_UINT8, BASE_DEC, NULL, 0x0,
2277       NULL, HFILL}
2278      },
2279     {&hf_docsis_tlv_svc_unavail_code,
2280      {"Service Not Available (Code)", "docsis_tlv.svcunavail.code",
2281       FT_UINT8, BASE_DEC, VALS(docsis_conf_code), 0x0,
2282       NULL, HFILL}
2283      },
2284     {&hf_docsis_tlv_cpe_ethernet,
2285      {"14 CPE Ethernet Addr", "docsis_tlv.cpe_ether",
2286       FT_ETHER, BASE_NONE, NULL, 0x0,
2287       "CPE Ethernet Addr", HFILL}
2288      },
2289     {&hf_docsis_tlv_bpi,
2290      {"17 Baseline Privacy Encoding", "docsis_tlv.bpi",
2291       FT_BYTES, BASE_NONE, NULL, 0x0,
2292       "Baseline Privacy Encoding", HFILL}
2293      },
2294     {&hf_docsis_tlv_max_cpe,
2295      {"18 Max # of CPE's", "docsis_tlv.maxcpe",
2296       FT_UINT8, BASE_DEC, NULL, 0x0,
2297       "Max Number of CPE's", HFILL}
2298      },
2299     {&hf_docsis_tlv_tftp_server_timestamp,
2300      {"19 TFTP Server Timestamp", "docsis_tlv.tftp_time",
2301       FT_UINT32, BASE_DEC, NULL, 0x0,
2302       "TFTP Server TimeStamp", HFILL}
2303      },
2304     {&hf_docsis_tlv_tftp_prov_modem_address,
2305      {"20 TFTP Server Provisioned Modem Addr", "docsis_tlv.tftpmodemaddr",
2306       FT_IPv4, BASE_NONE, NULL, 0x0,
2307       "TFTP Server Provisioned Modem Addr", HFILL}
2308      },
2309     {&hf_docsis_tlv_sw_upg_srvr,
2310      {"21 Software Upgrade Server", "docsis_tlv.sw_upg_srvr",
2311       FT_IPv4, BASE_NONE, NULL, 0x0,
2312       "Software Upgrade Server", HFILL}
2313      },
2314     {&hf_docsis_tlv_upclsfr,
2315      {"22 Upstream Classifier", "docsis_tlv.upclsfr",
2316       FT_BYTES, BASE_NONE, NULL, 0x0,
2317       NULL, HFILL}
2318      },
2319     {&hf_docsis_tlv_downclsfr,
2320      {"23 Downstream Classifier", "docsis_tlv.downclsfr",
2321       FT_BYTES, BASE_NONE, NULL, 0x0,
2322       NULL, HFILL}
2323      },
2324     {&hf_docsis_tlv_clsfr_ref,
2325      {".1 Classifier Ref", "docsis_tlv.clsfr.ref",
2326       FT_UINT8, BASE_DEC, NULL, 0x0,
2327       "Classifier Reference", HFILL}
2328      },
2329     {&hf_docsis_tlv_clsfr_id,
2330      {".2 Classifier ID", "docsis_tlv.clsfr.id",
2331       FT_UINT16, BASE_DEC, NULL, 0x0,
2332       "Classifier ID", HFILL}
2333      },
2334     {&hf_docsis_tlv_clsfr_sflow_ref,
2335      {".3 Service Flow Ref", "docsis_tlv.clsfr.sflowref",
2336       FT_UINT16, BASE_DEC, NULL, 0x0,
2337       "Service Flow Reference", HFILL}
2338      },
2339     {&hf_docsis_tlv_clsfr_sflow_id,
2340      {".4 Service Flow ID", "docsis_tlv.clsfr.sflowid",
2341       FT_UINT16, BASE_DEC, NULL, 0x0,
2342       "Service Flow ID", HFILL}
2343      },
2344     {&hf_docsis_tlv_clsfr_rule_pri,
2345      {".5 Rule Priority", "docsis_tlv.clsfr.rulepri",
2346       FT_UINT8, BASE_DEC, NULL, 0x0,
2347       "Rule Priority", HFILL}
2348      },
2349     {&hf_docsis_tlv_clsfr_act_state,
2350      {".6 Activation State", "docsis_tlv.clsfr.actstate",
2351       FT_BOOLEAN, BASE_NONE, TFS (&activation_tfs), 0x0,
2352       "Classifier Activation State", HFILL}
2353      },
2354     {&hf_docsis_tlv_clsfr_dsc_act,
2355      {".7 DSC Action", "docsis_tlv.clsfr.dscact",
2356       FT_UINT8, BASE_DEC, VALS (dsc_act_vals), 0x0,
2357       "Dynamic Service Change Action", HFILL}
2358      },
2359     {&hf_docsis_tlv_clsfr_err,
2360      {".8 Error Encodings", "docsis_tlv.clsfr.err",
2361       FT_BYTES, BASE_NONE, NULL, 0x0,
2362       "Error Encodings", HFILL}
2363      },
2364     {&hf_docsis_tlv_clsfr_err_param,
2365      {"..1 Param Subtype", "docsis_tlv.clsfr.err.param",
2366       FT_UINT8, BASE_DEC, NULL, 0x0,
2367       "Parameter Subtype", HFILL}
2368      },
2369     {&hf_docsis_tlv_clsfr_err_code,
2370      {"..2 Error Code", "docsis_tlv.clsfr.err.code",
2371       FT_UINT8, BASE_DEC, VALS(docsis_conf_code), 0x0,
2372       "TCP/UDP Destination Port End", HFILL}
2373      },
2374     {&hf_docsis_tlv_clsfr_err_msg,
2375      {"..3 Error Message", "docsis_tlv.clsfr.err.msg",
2376       FT_STRINGZ, BASE_NONE, NULL, 0x0,
2377       "Error Message", HFILL}
2378      },
2379     {&hf_docsis_tlv_ipclsfr,
2380      {".9 IP Classifier Encodings", "docsis_tlv.clsfr.ip",
2381       FT_BYTES, BASE_NONE, NULL, 0x0,
2382       "IP Classifier Encodings", HFILL}
2383      },
2384     {&hf_docsis_tlv_ipclsfr_tosmask,
2385      {"..1 Type Of Service Mask", "docsis_tlv.clsfr.ip.tosmask",
2386       FT_BYTES, BASE_NONE, NULL, 0x0,
2387       "Type Of Service Mask", HFILL}
2388      },
2389     {&hf_docsis_tlv_ipclsfr_ipproto,
2390      {"..2 IP Protocol", "docsis_tlv.clsfr.ip.ipproto",
2391       FT_UINT16, BASE_DEC, NULL, 0x0,
2392       "IP Protocol", HFILL}
2393      },
2394     {&hf_docsis_tlv_ipclsfr_src,
2395      {"..3 Source Address", "docsis_tlv.clsfr.ip.src",
2396       FT_IPv4, BASE_NONE, NULL, 0x0,
2397       "Source Address", HFILL}
2398      },
2399     {&hf_docsis_tlv_ipclsfr_dst,
2400      {"..4 Destination Address", "docsis_tlv.clsfr.ip.dst",
2401       FT_IPv4, BASE_NONE, NULL, 0x0,
2402       "Destination Address", HFILL}
2403      },
2404     {&hf_docsis_tlv_ipclsfr_srcmask,
2405      {"..5 Source Mask", "docsis_tlv.clsfr.ip.smask",
2406       FT_IPv4, BASE_NONE, NULL, 0x0,
2407       "Source Mask", HFILL}
2408      },
2409     {&hf_docsis_tlv_ipclsfr_dstmask,
2410      {"..6 Destination Mask", "docsis_tlv.clsfr.ip.dmask",
2411       FT_IPv4, BASE_NONE, NULL, 0x0,
2412       "Destination Mask", HFILL}
2413      },
2414     {&hf_docsis_tlv_ipclsfr_sport_start,
2415      {"..7 Source Port Start", "docsis_tlv.clsfr.ip.sportstart",
2416       FT_UINT16, BASE_DEC, NULL, 0x0,
2417       "TCP/UDP Source Port Start", HFILL}
2418      },
2419     {&hf_docsis_tlv_ipclsfr_sport_end,
2420      {"..8 Source Port End", "docsis_tlv.clsfr.ip.sportend",
2421       FT_UINT16, BASE_DEC, NULL, 0x0,
2422       "TCP/UDP Source Port End", HFILL}
2423      },
2424     {&hf_docsis_tlv_ipclsfr_dport_start,
2425      {"..9 Dest Port Start", "docsis_tlv.clsfr.ip.dportstart",
2426       FT_UINT16, BASE_DEC, NULL, 0x0,
2427       "TCP/UDP Destination Port Start", HFILL}
2428      },
2429     {&hf_docsis_tlv_ipclsfr_dport_end,
2430      {"..10 Dest Port End", "docsis_tlv.clsfr.ip.dportend",
2431       FT_UINT16, BASE_DEC, NULL, 0x0,
2432       "TCP/UDP Destination Port End", HFILL}
2433      },
2434     {&hf_docsis_tlv_ethclsfr,
2435      {".10 Ethernet Classifier Encodings", "docsis_tlv.clsfr.eth",
2436       FT_BYTES, BASE_NONE, NULL, 0x0,
2437       "Ethernet Classifier Encodings", HFILL}
2438      },
2439     {&hf_docsis_tlv_ethclsfr_dmac,
2440      {"..1 Dest Mac Address", "docsis_tlv.clsfr.eth.dmac",
2441       FT_ETHER, BASE_NONE, NULL, 0x0,
2442       "Destination Mac Address", HFILL}
2443      },
2444     {&hf_docsis_tlv_ethclsfr_smac,
2445      {"..2 Source Mac Address", "docsis_tlv.clsfr.eth.smac",
2446       FT_ETHER, BASE_NONE, NULL, 0x0,
2447       "Source Mac Address", HFILL}
2448      },
2449     {&hf_docsis_tlv_ethclsfr_ethertype,
2450      {"..3 Ethertype", "docsis_tlv.clsfr.eth.ethertype",
2451       FT_UINT24, BASE_HEX, NULL, 0x0,
2452       "Ethertype", HFILL}
2453      },
2454     {&hf_docsis_tlv_dot1qclsfr,
2455      {".11 802.1Q Classifier Encodings", "docsis_tlv.clsfr.dot1q",
2456       FT_BYTES, BASE_NONE, NULL, 0x0,
2457       "802.1Q Classifier Encodings", HFILL}
2458      },
2459     {&hf_docsis_tlv_dot1qclsfr_user_pri,
2460      {"..1 User Priority", "docsis_tlv.clsfr.dot1q.userpri",
2461       FT_UINT16, BASE_HEX, NULL, 0x0,
2462       "User Priority", HFILL}
2463      },
2464     {&hf_docsis_tlv_dot1qclsfr_vlanid,
2465      {"..2 VLAN id", "docsis_tlv.clsfr.dot1q.ethertype",
2466       FT_UINT16, BASE_DEC, NULL, 0x0,
2467       "VLAN Id", HFILL}
2468      },
2469     {&hf_docsis_tlv_dot1qclsfr_vendorspec,
2470      {"..43 Vendor Specific Encodings", "docsis_tlv.clsfr.dot1q.vendorspec",
2471       FT_BYTES, BASE_NONE, NULL, 0x0,
2472       "Vendor Specific Encodings", HFILL}
2473      },
2474     {&hf_docsis_tlv_clsfr_vendor_spc,
2475      {".43 Vendor Specific Encodings", "docsis_tlv.clsfr.vendor",
2476       FT_BYTES, BASE_NONE, NULL, 0x0,
2477       "Vendor Specific Encodings", HFILL}
2478      },
2479     {&hf_docsis_tlv_upsflow,
2480      {"24 Upstream Service Flow", "docsis_tlv.upsflow",
2481       FT_BYTES, BASE_NONE, NULL, 0x0,
2482       NULL, HFILL}
2483      },
2484     {&hf_docsis_tlv_downsflow,
2485      {"25 Downstream Service Flow", "docsis_tlv.downsflow",
2486       FT_BYTES, BASE_NONE, NULL, 0x0,
2487       NULL, HFILL}
2488      },
2489     {&hf_docsis_tlv_sflow_ref,
2490      {".1 Service Flow Ref", "docsis_tlv.sflow.ref",
2491       FT_UINT16, BASE_DEC, NULL, 0x0,
2492       "Service Flow Reference", HFILL}
2493      },
2494     {&hf_docsis_tlv_sflow_id,
2495      {".2 Service Flow Id", "docsis_tlv.sflow.id",
2496       FT_UINT32, BASE_DEC, NULL, 0x0,
2497       "Service Flow Id", HFILL}
2498      },
2499     {&hf_docsis_tlv_sflow_sid,
2500      {".3 Service Identifier", "docsis_tlv.sflow.sid",
2501       FT_UINT16, BASE_DEC, NULL, 0x0,
2502       "Service Identifier", HFILL}
2503      },
2504     {&hf_docsis_tlv_sflow_classname,
2505      {".4 Service Class Name", "docsis_tlv.sflow.cname",
2506       FT_STRINGZ, BASE_NONE, NULL, 0x0,
2507       "Service Class Name", HFILL}
2508      },
2509     {&hf_docsis_tlv_sflow_err,
2510      {".5 Error Encodings", "docsis_tlv.sflow.err",
2511       FT_BYTES, BASE_NONE, NULL, 0x0,
2512       "Error Encodings", HFILL}
2513      },
2514     {&hf_docsis_tlv_sflow_err_param,
2515      {"..1 Param Subtype", "docsis_tlv.sflow.err.param",
2516       FT_UINT8, BASE_DEC, NULL, 0x0,
2517       "Parameter Subtype", HFILL}
2518      },
2519     {&hf_docsis_tlv_sflow_err_code,
2520      {"..2 Error Code", "docsis_tlv.sflow.err.code",
2521       FT_UINT8, BASE_DEC, VALS(docsis_conf_code), 0x0,
2522       "Error Code", HFILL}
2523      },
2524     {&hf_docsis_tlv_sflow_err_msg,
2525      {"..3 Error Message", "docsis_tlv.sflow.err.msg",
2526       FT_STRINGZ, BASE_NONE, NULL, 0x0,
2527       "Error Message", HFILL}
2528      },
2529     {&hf_docsis_tlv_sflow_qos_param,
2530      {".6 QOS Parameter Set", "docsis_tlv.sflow.qos",
2531       FT_UINT8, BASE_HEX, VALS (qos_param_vals), 0x0,
2532       "QOS Parameter Set", HFILL}
2533      },
2534     {&hf_docsis_tlv_sflow_traf_pri,
2535      {".7 Traffic Priority", "docsis_tlv.sflow.trafpri",
2536       FT_UINT8, BASE_DEC, NULL, 0x0,
2537       "Traffic Priority", HFILL}
2538      },
2539     {&hf_docsis_tlv_sflow_max_sus,
2540      {".8 Maximum Sustained Traffic Rate (bps)",
2541       "docsis_tlv.sflow.maxtrafrate",
2542       FT_UINT32, BASE_DEC, NULL, 0x0,
2543       "Maximum Sustained Traffic Rate (bps)", HFILL}
2544      },
2545     {&hf_docsis_tlv_sflow_max_burst,
2546      {".9 Maximum Burst (bps)", "docsis_tlv.sflow.maxburst",
2547       FT_UINT32, BASE_DEC, NULL, 0x0,
2548       "Maximum Burst (bps)", HFILL}
2549      },
2550     {&hf_docsis_tlv_sflow_min_traf,
2551      {".10 Minimum Traffic Rate (bps)", "docsis_tlv.sflow.mintrafrate",
2552       FT_UINT32, BASE_DEC, NULL, 0x0,
2553       "Minimum Traffic Rate (bps)", HFILL}
2554      },
2555     {&hf_docsis_tlv_sflow_ass_min_pkt_size,
2556      {".11 Assumed Min Reserved Packet Size",
2557       "docsis_tlv.sflow.assumed_min_pkt_size",
2558       FT_UINT16, BASE_DEC, NULL, 0x0,
2559       "Assumed Minimum Reserved Packet Size", HFILL}
2560      },
2561     {&hf_docsis_tlv_sflow_timeout_active,
2562      {".12 Timeout for Active Params (secs)", "docsis_tlv.sflow.act_timeout",
2563       FT_UINT16, BASE_DEC, NULL, 0x0,
2564       "Timeout for Active Params (secs)", HFILL}
2565      },
2566     {&hf_docsis_tlv_sflow_timeout_admitted,
2567      {".13 Timeout for Admitted Params (secs)",
2568       "docsis_tlv.sflow.adm_timeout",
2569       FT_UINT16, BASE_DEC, NULL, 0x0,
2570       "Timeout for Admitted Params (secs)", HFILL}
2571      },
2572     {&hf_docsis_tlv_sflow_max_down_latency,
2573      {".14 Maximum Downstream Latency (usec)",
2574       "docsis_tlv.sflow.max_down_lat",
2575       FT_UINT32, BASE_DEC, NULL, 0x0,
2576       "Maximum Downstream Latency (usec)", HFILL}
2577      },
2578     {&hf_docsis_tlv_sflow_max_concat_burst,
2579      {".14 Max Concat Burst", "docsis_tlv.sflow.maxconcat",
2580       FT_UINT16, BASE_DEC, NULL, 0x0,
2581       "Max Concatenated Burst", HFILL}
2582      },
2583     {&hf_docsis_tlv_sflow_sched_type,
2584      {".15 Scheduling Type", "docsis_tlv.sflow.schedtype",
2585       FT_UINT32, BASE_HEX, VALS (sched_type_vals), 0x0,
2586       "Scheduling Type", HFILL}
2587      },
2588     {&hf_docsis_tlv_sflow_reqxmit_pol,
2589      {".16 Request/Transmission Policy", "docsis_tlv.sflow.reqxmitpol",
2590       FT_UINT32, BASE_HEX, NULL, 0x0,
2591       "Request/Transmission Policy", HFILL}
2592      },
2593     {&hf_docsis_tlv_sflow_nominal_polling,
2594      {".17 Nominal Polling Interval(usec)",
2595       "docsis_tlv.sflow.nominal_polling",
2596       FT_UINT32, BASE_DEC, NULL, 0x0,
2597       "Nominal Polling Interval(usec)", HFILL}
2598      },
2599     {&hf_docsis_tlv_sflow_tolerated_jitter,
2600      {".18 Tolerated Poll Jitter (usec)", "docsis_tlv.sflow.toler_jitter",
2601       FT_UINT32, BASE_DEC, NULL, 0x0,
2602       "Tolerated Poll Jitter (usec)", HFILL}
2603      },
2604     {&hf_docsis_tlv_sflow_ugs_size,
2605      {".19 Unsolicited Grant Size (bytes)", "docsis_tlv.sflow.ugs_size",
2606       FT_UINT16, BASE_DEC, NULL, 0x0,
2607       "Unsolicited Grant Size (bytes)", HFILL}
2608      },
2609     {&hf_docsis_tlv_sflow_nom_grant_intvl,
2610      {".20 Nominal Grant Interval (usec)", "docsis_tlv.sflow.nom_grant_intvl",
2611       FT_UINT32, BASE_DEC, NULL, 0x0,
2612       "Nominal Grant Interval (usec)", HFILL}
2613      },
2614     {&hf_docsis_tlv_sflow_tol_grant_jitter,
2615      {".21 Tolerated Grant Jitter (usec)",
2616       "docsis_tlv.sflow.tol_grant_jitter",
2617       FT_UINT32, BASE_DEC, NULL, 0x0,
2618       "Tolerated Grant Jitter (usec)", HFILL}
2619      },
2620     {&hf_docsis_tlv_sflow_grants_per_intvl,
2621      {".22 Grants Per Interval", "docsis_tlv.sflow.grnts_per_intvl",
2622       FT_UINT8, BASE_DEC, NULL, 0x0,
2623       "Grants Per Interval", HFILL}
2624      },
2625     {&hf_docsis_tlv_sflow_ip_tos_overwrite,
2626      {".23 IP TOS Overwrite", "docsis_tlv.sflow.iptos_overwrite",
2627       FT_UINT16, BASE_HEX, NULL, 0x0,
2628       "IP TOS Overwrite", HFILL}
2629      },
2630     {&hf_docsis_tlv_sflow_ugs_timeref,
2631      {".24 UGS Time Reference", "docsis_tlv.sflow.ugs_timeref",
2632       FT_UINT32, BASE_DEC, NULL, 0x0,
2633       "UGS Time Reference", HFILL}
2634      },
2635     {&hf_docsis_tlv_sflow_vendor_spec,
2636      {".43 Vendor Specific Encodings", "docsis_tlv.sflow.vendorspec",
2637       FT_BYTES, BASE_NONE, NULL, 0x0,
2638       "Vendor Specific Encodings", HFILL}
2639      },
2640     {&hf_docsis_tlv_phs,
2641      {"26 PHS Rules", "docsis_tlv.phs",
2642       FT_BYTES, BASE_NONE, NULL, 0x0,
2643       "PHS Rules", HFILL}
2644      },
2645     {&hf_docsis_tlv_phs_class_ref,
2646      {".1 Classifier Reference", "docsis_tlv.phs.classref",
2647       FT_UINT8, BASE_DEC, NULL, 0x0,
2648       "Classifier Reference", HFILL}
2649      },
2650     {&hf_docsis_tlv_phs_class_id,
2651      {".2 Classifier Id", "docsis_tlv.phs.classid",
2652       FT_UINT16, BASE_DEC, NULL, 0x0,
2653       "Classifier Id", HFILL}
2654      },
2655     {&hf_docsis_tlv_phs_sflow_ref,
2656      {".3 Service flow reference", "docsis_tlv.phs.sflowref",
2657       FT_UINT16, BASE_DEC, NULL, 0x0,
2658       "Service Flow Reference", HFILL}
2659      },
2660     {&hf_docsis_tlv_phs_sflow_id,
2661      {".4 Service flow Id", "docsis_tlv.phs.sflowid",
2662       FT_UINT16, BASE_DEC, NULL, 0x0,
2663       "Service Flow Id", HFILL}
2664      },
2665     {&hf_docsis_tlv_phs_dsc_action,
2666      {".5 DSC Action", "docsis_tlv.phs.dscaction",
2667       FT_UINT8, BASE_DEC, VALS (action_vals), 0x0,
2668       "Dynamic Service Change Action", HFILL}
2669      },
2670     {&hf_docsis_tlv_phs_err,
2671      {".6 Error Encodings", "docsis_tlv.phs.err",
2672       FT_BYTES, BASE_NONE, NULL, 0x0,
2673       "Error Encodings", HFILL}
2674      },
2675     {&hf_docsis_tlv_phs_err_param,
2676      {"..1 Param Subtype", "docsis_tlv.phs.err.param",
2677       FT_UINT8, BASE_DEC, NULL, 0x0,
2678       "Parameter Subtype", HFILL}
2679      },
2680     {&hf_docsis_tlv_phs_err_code,
2681      {"..2 Error Code", "docsis_tlv.phs.err.code",
2682       FT_UINT8, BASE_DEC, NULL, 0x0,
2683       "Error Code", HFILL}
2684      },
2685     {&hf_docsis_tlv_phs_err_msg,
2686      {"..3 Error Message", "docsis_tlv.phs.err.msg",
2687       FT_STRINGZ, BASE_NONE, NULL, 0x0,
2688       "Error Message", HFILL}
2689      },
2690     {&hf_docsis_tlv_phs_phsf,
2691      {".7 PHS Field", "docsis_tlv.phs.phsf",
2692       FT_BYTES, BASE_NONE, NULL, 0x0,
2693       "PHS Field", HFILL}
2694      },
2695     {&hf_docsis_tlv_phs_phsi,
2696      {".8 PHS Index", "docsis_tlv.phs.phsi",
2697       FT_UINT8, BASE_DEC, NULL, 0x0,
2698       "PHS Index", HFILL}
2699      },
2700     {&hf_docsis_tlv_phs_phsm,
2701      {".9 PHS Mask", "docsis_tlv.phs.phsm",
2702       FT_BYTES, BASE_NONE, NULL, 0x0,
2703       "PHS Mask", HFILL}
2704      },
2705     {&hf_docsis_tlv_phs_phss,
2706      {".10 PHS Size", "docsis_tlv.phs.phss",
2707       FT_UINT8, BASE_DEC, NULL, 0x0,
2708       "PHS Size", HFILL}
2709      },
2710     {&hf_docsis_tlv_phs_phsv,
2711      {".11 PHS Verify", "docsis_tlv.phs.phsv",
2712       FT_BOOLEAN, BASE_NONE, TFS (&verify_tfs), 0x0,
2713       "PHS Verify", HFILL}
2714      },
2715     {&hf_docsis_tlv_phs_vendorspec,
2716      {".43 PHS Vendor Specific", "docsis_tlv.phs.vendorspec",
2717       FT_BYTES, BASE_NONE, NULL, 0x0,
2718       "PHS Vendor Specific", HFILL}
2719      },
2720     {&hf_docsis_tlv_hmac_digest,
2721      {"27 HMAC Digest", "docsis_tlv.hmac_digest",
2722       FT_BYTES, BASE_NONE, NULL, 0x0,
2723       "HMAC Digest", HFILL}
2724      },
2725     {&hf_docsis_tlv_max_classifiers,
2726      {"28 Max # of Classifiers", "docsis_tlv.maxclass",
2727       FT_UINT16, BASE_DEC, NULL, 0x0,
2728       "Max # of Classifiers", HFILL}
2729      },
2730     {&hf_docsis_tlv_privacy_enable,
2731      {"29 Privacy Enable", "docsis_tlv.bpi_en",
2732       FT_BOOLEAN, BASE_NONE, TFS (&ena_dis_tfs), 0x0,
2733       "Privacy Enable", HFILL}
2734      },
2735     {&hf_docsis_tlv_auth_block,
2736      {"30 Auth Block", "docsis_tlv.auth_block",
2737       FT_BYTES, BASE_NONE, NULL, 0x0,
2738       "Auth Block", HFILL}
2739      },
2740     {&hf_docsis_tlv_key_seq_num,
2741      {"31 Key Sequence Number", "docsis_tlv.key_seq",
2742       FT_BYTES, BASE_NONE, NULL, 0x0,
2743       "Key Sequence Number", HFILL}
2744      },
2745     {&hf_docsis_tlv_mfgr_cvc,
2746      {"32 Manufacturer CVC", "docsis_tlv.mfgr_cvc",
2747       FT_BYTES, BASE_NONE, NULL, 0x0,
2748       "Manufacturer CVC", HFILL}
2749      },
2750     {&hf_docsis_tlv_cosign_cvc,
2751      {"33 Co-Signer CVC", "docsis_tlv.cosign_cvc",
2752       FT_BYTES, BASE_NONE, NULL, 0x0,
2753       "Co-Signer CVC", HFILL}
2754      },
2755     {&hf_docsis_tlv_snmpv3_kick,
2756      {"34 SNMPv3 Kickstart Value", "docsis_tlv.snmpv3",
2757       FT_BYTES, BASE_NONE, NULL, 0x0,
2758       "SNMPv3 Kickstart Value", HFILL}
2759      },
2760     {&hf_docsis_tlv_snmpv3_kick_name,
2761      {".1 SNMPv3 Kickstart Security Name", "docsis_tlv.snmpv3.secname",
2762       FT_STRING, BASE_NONE, NULL, 0x0,
2763       "SNMPv3 Kickstart Security Name", HFILL}
2764      },
2765     {&hf_docsis_tlv_snmpv3_kick_publicnum,
2766      {".2 SNMPv3 Kickstart Manager Public Number", "docsis_tlv.snmpv3.publicnum",
2767       FT_BYTES, BASE_NONE, NULL, 0x0,
2768       "SNMPv3 Kickstart Value Manager Public Number", HFILL}
2769      },
2770     {&hf_docsis_tlv_subs_mgmt_ctrl,
2771      {"35 Subscriber Management Control", "docsis_tlv.subsmgmtctrl",
2772       FT_BYTES, BASE_NONE, NULL, 0x0,
2773       "Subscriber Management Control", HFILL}
2774      },
2775     {&hf_docsis_tlv_subs_mgmt_ip_table,
2776      {"36 Subscriber Management CPE IP Table", "docsis_tlv.subsiptable",
2777       FT_BYTES, BASE_NONE, NULL, 0x0,
2778       "Subscriber Management CPE IP Table", HFILL}
2779      },
2780     {&hf_docsis_tlv_subs_mgmt_ip_entry,
2781      {"Subscriber Management CPE IP Entry", "docsis_tlv.subsipentry",
2782       FT_IPv4, BASE_NONE, NULL, 0x0,
2783       NULL, HFILL}
2784      },
2785     {&hf_docsis_tlv_subs_mgmt_filter_grps,
2786      {"37 Subscriber Management Filter Groups", "docsis_tlv.subsfltrgrps",
2787       FT_BYTES, BASE_NONE, NULL, 0x0,
2788       "Subscriber Management Filter Groups", HFILL}
2789      },
2790     {&hf_docsis_tlv_vendor_spec,
2791      {"43 Vendor Specific Encodings", "docsis_tlv.vendorspec",
2792       FT_BYTES, BASE_NONE, NULL, 0x0,
2793       "Vendor Specific Encodings", HFILL}
2794      },
2795     {&hf_docsis_tlv_rng_tech,
2796      {"Ranging Technique", "docsis_tlv.rng_tech",
2797       FT_UINT8, BASE_DEC, VALS (rng_tech_vals), 0x0,
2798       NULL, HFILL}
2799      },
2800   };
2801
2802 /* Setup protocol subtree array */
2803   static gint *ett[] = {
2804     &ett_docsis_tlv,
2805     &ett_docsis_tlv_cos,
2806     &ett_docsis_tlv_mcap,
2807     &ett_docsis_tlv_clsfr,
2808     &ett_docsis_tlv_clsfr_ip,
2809     &ett_docsis_tlv_clsfr_eth,
2810     &ett_docsis_tlv_clsfr_err,
2811     &ett_docsis_tlv_clsfr_dot1q,
2812     &ett_docsis_tlv_reqxmitpol,
2813     &ett_docsis_tlv_sflow_err,
2814     &ett_docsis_tlv_phs,
2815     &ett_docsis_tlv_phs_err,
2816     &ett_docsis_tlv_svc_unavail,
2817     &ett_docsis_tlv_snmpv3_kick,
2818   };
2819
2820 /* Register the protocol name and description */
2821   proto_docsis_tlv = proto_register_protocol ("DOCSIS Appendix C TLV's",
2822                                               "DOCSIS TLVs", "docsis_tlv");
2823
2824 /* Required function calls to register the header fields and subtrees used */
2825   proto_register_field_array (proto_docsis_tlv, hf, array_length (hf));
2826   proto_register_subtree_array (ett, array_length (ett));
2827
2828   register_dissector ("docsis_tlv", dissect_tlv, proto_docsis_tlv);
2829 }
2830
2831
2832 /* If this dissector uses sub-dissector registration add a registration routine.
2833    This format is required because a script is used to find these routines and
2834    create the code that calls these routines.
2835 */
2836 void
2837 proto_reg_handoff_docsis_tlv (void)
2838 {
2839   dissector_handle_t docsis_tlv_handle;
2840
2841   docsis_tlv_handle = find_dissector ("docsis_tlv");
2842   docsis_vsif_handle = find_dissector("docsis_vsif");
2843
2844   dissector_add ("docsis", 0xFF, docsis_tlv_handle);
2845
2846 }