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