Allocate correct size of range.
[obnox/wireshark/wip.git] / plugins / docsis / packet-type29ucd.c
1 /* packet-type29ucd.c
2  * Routines for Type 29 UCD - DOCSIS 2.0 only - Message dissection
3  * Copyright 2003, Brian Wheeler <brian.wheeler[AT]arrisi.com>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <epan/packet.h>
31
32 #define type29ucd_SYMBOL_RATE 1
33 #define type29ucd_FREQUENCY 2
34 #define type29ucd_PREAMBLE 3
35 #define type29ucd_BURST_DESCR 4
36 #define type29ucd_BURST_DESCR5 5
37 #define type29ucd_EXT_PREAMBLE 6
38 #define type29ucd_SCDMA_MODE_ENABLE 7
39 #define type29ucd_SCDMA_SPREADING_INTERVAL 8
40 #define type29ucd_SCDMA_CODES_PER_MINI_SLOT 9
41 #define type29ucd_SCDMA_ACTIVE_CODES 10
42 #define type29ucd_SCDMA_CODE_HOPPING_SEED 11
43 #define type29ucd_SCDMA_US_RATIO_NUM 12
44 #define type29ucd_SCDMA_US_RATIO_DENOM 13
45 #define type29ucd_SCDMA_TIMESTAMP_SNAPSHOT 14
46 #define type29ucd_MAINTAIN_POWER_SPECTRAL_DENSITY 15
47 #define type29ucd_RANGING_REQUIRED 16
48
49 #define type29ucd_MODULATION 1
50 #define type29ucd_DIFF_ENCODING 2
51 #define type29ucd_PREAMBLE_LEN 3
52 #define type29ucd_PREAMBLE_VAL_OFF 4
53 #define type29ucd_FEC 5
54 #define type29ucd_FEC_CODEWORD 6
55 #define type29ucd_SCRAMBLER_SEED 7
56 #define type29ucd_MAX_BURST 8
57 #define type29ucd_GUARD_TIME 9
58 #define type29ucd_LAST_CW_LEN 10
59 #define type29ucd_SCRAMBLER_ONOFF 11
60 #define type29ucd_RS_INT_DEPTH 12
61 #define type29ucd_RS_INT_BLOCK 13
62 #define type29ucd_PREAMBLE_TYPE 14
63 #define type29ucd_SCMDA_SCRAMBLER_ONOFF 15
64 #define type29ucd_SCDMA_CODES_PER_SUBFRAME 16
65 #define type29ucd_SCDMA_FRAMER_INT_STEP_SIZE 17
66 #define type29ucd_TCM_ENABLED 18
67
68 #define IUC_REQUEST 1
69 #define IUC_REQ_DATA 2
70 #define IUC_INIT_MAINT 3
71 #define IUC_STATION_MAINT 4
72 #define IUC_SHORT_DATA_GRANT 5
73 #define IUC_LONG_DATA_GRANT 6
74 #define IUC_NULL_IE 7
75 #define IUC_DATA_ACK 8
76 #define IUC_ADV_PHY_SHORT_DATA_GRANT 9
77 #define IUC_ADV_PHY_LONG_DATA_GRANT 10
78 #define IUC_ADV_PHY_UGS 11
79 #define IUC_RESERVED12 12
80 #define IUC_RESERVED13 13
81 #define IUC_RESERVED14 14
82 #define IUC_EXPANSION 15
83
84 /* Initialize the protocol and registered fields */
85 static int proto_docsis_type29ucd = -1;
86
87 static int hf_docsis_type29ucd_upstream_chid = -1;
88 static int hf_docsis_type29ucd_config_ch_cnt = -1;
89 static int hf_docsis_type29ucd_mini_slot_size = -1;
90 static int hf_docsis_type29ucd_down_chid = -1;
91 static int hf_docsis_type29ucd_symbol_rate = -1;
92 static int hf_docsis_type29ucd_frequency = -1;
93 static int hf_docsis_type29ucd_preamble_pat = -1;
94 static int hf_docsis_type29ucd_iuc = -1;
95 static int hf_docsis_type29ucd_ext_preamble = -1;
96 static int hf_docsis_type29ucd_scdma_mode_enable = -1;
97 static int hf_docsis_type29ucd_scdma_spreading_interval = -1;
98 static int hf_docsis_type29ucd_scdma_codes_per_mini_slot = -1;
99 static int hf_docsis_type29ucd_scdma_active_codes = -1;
100 static int hf_docsis_type29ucd_scdma_code_hopping_seed = -1;
101 static int hf_docsis_type29ucd_scdma_us_ratio_num = -1;
102 static int hf_docsis_type29ucd_scdma_us_ratio_denom = -1;
103 static int hf_docsis_type29ucd_scdma_timestamp_snapshot = -1;
104 static int hf_docsis_type29ucd_maintain_power_spectral_density = -1;
105 static int hf_docsis_type29ucd_ranging_required = -1;
106
107 static int hf_docsis_burst_mod_type = -1;
108 static int hf_docsis_burst_diff_encoding = -1;
109 static int hf_docsis_burst_preamble_len = -1;
110 static int hf_docsis_burst_preamble_val_off = -1;
111 static int hf_docsis_burst_fec = -1;
112 static int hf_docsis_burst_fec_codeword = -1;
113 static int hf_docsis_burst_scrambler_seed = -1;
114 static int hf_docsis_burst_max_burst = -1;
115 static int hf_docsis_burst_guard_time = -1;
116 static int hf_docsis_burst_last_cw_len = -1;
117 static int hf_docsis_burst_scrambler_onoff = -1;
118 static int hf_docsis_rs_int_depth = -1;
119 static int hf_docsis_rs_int_block = -1;
120 static int hf_docsis_preamble_type = -1;
121 static int hf_docsis_scdma_scrambler_onoff = -1;
122 static int hf_docsis_scdma_codes_per_subframe = -1;
123 static int hf_docsis_scdma_framer_int_step_size = -1;
124 static int hf_docsis_tcm_enabled = -1;
125
126
127 /* Initialize the subtree pointers */
128 static gint ett_docsis_type29ucd = -1;
129 static gint ett_burst_descr = -1;
130
131 static const value_string channel_tlv_vals[] _U_ = {
132      {type29ucd_SYMBOL_RATE, "Symbol Rate"},
133      {type29ucd_FREQUENCY, "Frequency"},
134      {type29ucd_PREAMBLE, "Preamble Pattern"},
135      {type29ucd_BURST_DESCR, "Burst Descriptor"},
136      {type29ucd_BURST_DESCR5, "Burst Descriptor DOCSIS 2.0"},
137      {type29ucd_EXT_PREAMBLE, "Extended Preamble Pattern"},
138      {type29ucd_SCDMA_MODE_ENABLE, "SCDMA Mode Enabled"},
139      {type29ucd_SCDMA_SPREADING_INTERVAL, "SCDMA Spreading Intervals per Frame"},
140      {type29ucd_SCDMA_CODES_PER_MINI_SLOT, "SCDMA Codes per Mini-slot"},
141      {type29ucd_SCDMA_ACTIVE_CODES, "SCDMA Number of Active Codes"},
142      {type29ucd_SCDMA_CODE_HOPPING_SEED, "SCDMA Code Hopping Seed"},
143      {type29ucd_SCDMA_US_RATIO_NUM, "SCDMA US ratio numerator M"},
144      {type29ucd_SCDMA_US_RATIO_DENOM, "SCDMA US ratio denominator N"},
145      {type29ucd_SCDMA_TIMESTAMP_SNAPSHOT, "SCDMA Timestamp Snapshot"},
146      {type29ucd_MAINTAIN_POWER_SPECTRAL_DENSITY, "Maintain Power Spectral Density"},
147      {type29ucd_RANGING_REQUIRED, "Ranging Required"},
148      {0, NULL}
149 };
150
151 static const value_string on_off_vals[] = {
152   {1, "On"},
153   {2, "Off"},
154   {0, NULL}
155 };
156
157 static const value_string mod_vals2[] = {
158      {1, "QPSK"},
159      {2, "QAM16"},
160      {3, "QAM8"},
161      {4, "QAM32"},
162      {5, "QAM64"},
163      {6, "QAM128 (S-CDMA)"},
164      {0, NULL}
165 };
166
167 value_string iuc_vals2[] = {
168      {IUC_REQUEST, "Request"},
169      {IUC_REQ_DATA, "REQ/Data"},
170      {IUC_INIT_MAINT, "Initial Maintenance"},
171      {IUC_STATION_MAINT, "Station Maintenance"},
172      {IUC_SHORT_DATA_GRANT, "Short Data Grant"},
173      {IUC_LONG_DATA_GRANT, "Long Data Grant"},
174      {IUC_NULL_IE, "NULL IE"},
175      {IUC_DATA_ACK, "Data Ack"},
176      {IUC_ADV_PHY_SHORT_DATA_GRANT, "Advanced Phy Short Data Grant"},
177      {IUC_ADV_PHY_LONG_DATA_GRANT, "Advanced Phy Long Data Grant"},
178      {IUC_ADV_PHY_UGS, "Advanced Phy UGS"},
179      {IUC_RESERVED12, "Reserved 12"},
180      {IUC_RESERVED13, "Reserved 13"},
181      {IUC_RESERVED14, "Reserved 14"},
182      {IUC_EXPANSION, "IUC Expansion"},
183      {0, NULL}
184 };
185
186 static const value_string last_cw_len_vals[] = {
187   {1, "Fixed"},
188   {2, "Shortened"},
189   {0, NULL}
190 };
191 /* Code to actually dissect the packets */
192 static void
193 dissect_type29ucd (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
194 {
195   guint16 pos, endtlvpos;
196   guint8 type, length;
197   guint8 tlvlen, tlvtype;
198   proto_tree *burst_descr_tree;
199   proto_item *it;
200   proto_tree *type29ucd_tree;
201   proto_item *type29ucd_item;
202   guint16 len;
203   guint8 upchid, symrate;
204
205   len = tvb_length_remaining (tvb, 0);
206   upchid = tvb_get_guint8 (tvb, 0);
207
208   /* if the upstream Channel ID is 0 then this is for Telephony Return) */
209   col_clear (pinfo->cinfo, COL_INFO);
210   if (upchid > 0)
211         col_add_fstr (pinfo->cinfo, COL_INFO,
212                       "type29ucd Message:  Channel ID = %u (U%u)", upchid,
213                       upchid - 1);
214   else
215         col_add_fstr (pinfo->cinfo, COL_INFO,
216                       "type29ucd Message:  Channel ID = %u (Telephony Return)",
217                       upchid);
218
219   if (tree)
220     {
221       type29ucd_item =
222         proto_tree_add_protocol_format (tree, proto_docsis_type29ucd, tvb, 0,
223                                         tvb_length_remaining (tvb, 0),
224                                         "type29ucd Message");
225       type29ucd_tree = proto_item_add_subtree (type29ucd_item, ett_docsis_type29ucd);
226       proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_upstream_chid, tvb, 0, 1,
227                            FALSE);
228       proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_config_ch_cnt, tvb, 1, 1,
229                            FALSE);
230       proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_mini_slot_size, tvb, 2, 1,
231                            FALSE);
232       proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_down_chid, tvb, 3, 1,
233                            FALSE);
234
235       pos = 4;
236       while (pos < len)
237         {
238           type = tvb_get_guint8 (tvb, pos++);
239           length = tvb_get_guint8 (tvb, pos++);
240           switch (type)
241             {
242             case type29ucd_SYMBOL_RATE:
243               if (length == 1)
244                 {
245                   symrate = tvb_get_guint8 (tvb, pos);
246                   proto_tree_add_uint (type29ucd_tree, hf_docsis_type29ucd_symbol_rate,
247                                        tvb, pos, length, symrate * 160);
248                 }
249               else
250                 {
251                   THROW (ReportedBoundsError);
252                 }
253               pos = pos + length;
254               break;
255             case type29ucd_FREQUENCY:
256               if (length == 4)
257                 {
258                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_frequency, tvb,
259                                        pos, length, FALSE);
260                   pos = pos + length;
261                 }
262               else
263                 {
264                   THROW (ReportedBoundsError);
265                 }
266               break;
267             case type29ucd_PREAMBLE:
268               proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_preamble_pat, tvb,
269                                    pos, length, FALSE);
270               pos = pos + length;
271               break;
272 /* DOCSIS 2.0 UCD TLV definitions 
273  * #define type29ucd_EXT_PREAMBLE 6
274  * #define type29ucd_SCDMA_MODE_ENABLE 7
275  * #define type29ucd_SCDMA_SPREADING_INTERVAL 8
276  * #define type29ucd_SCDMA_CODES_PER_MINI_SLOT 9
277  * #define type29ucd_SCDMA_ACTIVE_CODES 10
278  * #define type29ucd_SCDMA_CODE_HOPPING_SEED 11
279  * #define type29ucd_SCDMA_US_RATIO_NUM 12
280  * #define type29ucd_SCDMA_US_RATIO_DENOM 13
281  * #define type29ucd_SCDMA_TIMESTAMP_SNAPSHOT 14
282  * #define type29ucd_MAINTAIN_POWER_SPECTRAL_DENSITY 15
283  * #define type29ucd_RANGING_REQUIRED 16
284  */
285             case type29ucd_EXT_PREAMBLE:
286               proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_ext_preamble, tvb,
287                                    pos, length, FALSE);
288               pos = pos + length;
289               break;
290             case type29ucd_SCDMA_MODE_ENABLE:
291               if (length == 1)
292                 {
293                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_scdma_mode_enable,
294                                        tvb, pos, length, FALSE);
295                 }
296               else
297                 {
298                   THROW (ReportedBoundsError);
299                 }
300               pos = pos + length;
301               break;
302             case type29ucd_SCDMA_SPREADING_INTERVAL:
303               if (length == 1)
304                 {
305                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_scdma_spreading_interval,
306                                        tvb, pos, length, FALSE);
307                 }
308               else
309                 {
310                   THROW (ReportedBoundsError);
311                 }
312               pos = pos + length;
313               break;
314             case type29ucd_SCDMA_CODES_PER_MINI_SLOT:
315               if (length == 1)
316                 {
317                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_scdma_codes_per_mini_slot,
318                                        tvb, pos, length, FALSE);
319                 }
320               else
321                 {
322                   THROW (ReportedBoundsError);
323                 }
324               pos = pos + length;
325               break;
326             case type29ucd_SCDMA_ACTIVE_CODES:
327               if (length == 1)
328                 {
329                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_scdma_active_codes,
330                                        tvb, pos, length, FALSE);
331                 }
332               else
333                 {
334                   THROW (ReportedBoundsError);
335                 }
336               pos = pos + length;
337               break;
338             case type29ucd_SCDMA_CODE_HOPPING_SEED:
339               if (length == 2)
340                 {
341                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_scdma_code_hopping_seed,
342                                        tvb, pos, length, FALSE);
343                 }
344               else
345                 {
346                   THROW (ReportedBoundsError);
347                 }
348               pos = pos + length;
349               break;
350             case type29ucd_SCDMA_US_RATIO_NUM:
351               if (length == 2)
352                 {
353                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_scdma_us_ratio_num,
354                                        tvb, pos, length, FALSE);
355                 }
356               else
357                 {
358                   THROW (ReportedBoundsError);
359                 }
360               pos = pos + length;
361               break;
362             case type29ucd_SCDMA_US_RATIO_DENOM:
363               if (length == 2)
364                 {
365                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_scdma_us_ratio_denom,
366                                        tvb, pos, length, FALSE);
367                 }
368               else
369                 {
370                   THROW (ReportedBoundsError);
371                 }
372               pos = pos + length;
373               break;
374             case type29ucd_SCDMA_TIMESTAMP_SNAPSHOT:
375               if (length == 9)
376                 {
377                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_scdma_timestamp_snapshot,
378                                        tvb, pos, length, FALSE);
379                 }
380               else
381                 {
382                   THROW (ReportedBoundsError);
383                 }
384               pos = pos + length;
385               break;
386             case type29ucd_MAINTAIN_POWER_SPECTRAL_DENSITY:
387               if (length == 1)
388                 {
389                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_maintain_power_spectral_density,
390                                        tvb, pos, length, FALSE);
391                 }
392               else
393                 {
394                   THROW (ReportedBoundsError);
395                 }
396               pos = pos + length;
397               break;
398             case type29ucd_RANGING_REQUIRED:
399               if (length == 1)
400                 {
401                   proto_tree_add_item (type29ucd_tree, hf_docsis_type29ucd_ranging_required,
402                                        tvb, pos, length, FALSE);
403                 }
404               else
405                 {
406                   THROW (ReportedBoundsError);
407                 }
408               pos = pos + length;
409               break;           
410 /* DOCSIS 1.1 BURST DESCRIPTOR */
411              case type29ucd_BURST_DESCR:
412               it =
413                 proto_tree_add_text (type29ucd_tree, tvb, pos, length,
414                                      "4 Burst Descriptor (Length = %u)",
415                                      length);
416               burst_descr_tree = proto_item_add_subtree (it, ett_burst_descr);
417               proto_tree_add_item (burst_descr_tree, hf_docsis_type29ucd_iuc, tvb,
418                                    pos++, 1, FALSE);
419               endtlvpos = pos + length - 1;
420               while (pos < endtlvpos)
421                 {
422                   tlvtype = tvb_get_guint8 (tvb, pos++);
423                   tlvlen = tvb_get_guint8 (tvb, pos++);
424                   switch (tlvtype)
425                     {
426                     case type29ucd_MODULATION:
427                       if (tlvlen == 1)
428                         {
429                           proto_tree_add_item (burst_descr_tree,
430                                                hf_docsis_burst_mod_type, tvb,
431                                                pos, tlvlen, FALSE);
432                         }
433                       else
434                         {
435                           THROW (ReportedBoundsError);
436                         }
437                       break;
438                     case type29ucd_DIFF_ENCODING:
439                       if (tlvlen == 1)
440                         {
441                           proto_tree_add_item (burst_descr_tree,
442                                                hf_docsis_burst_diff_encoding,
443                                                tvb, pos, tlvlen, FALSE);
444                         }
445                       else
446                         {
447                           THROW (ReportedBoundsError);
448                         }
449                       break;
450                     case type29ucd_PREAMBLE_LEN:
451                       if (tlvlen == 2)
452                         {
453                           proto_tree_add_item (burst_descr_tree,
454                                                hf_docsis_burst_preamble_len,
455                                                tvb, pos, tlvlen, FALSE);
456                         }
457                       else
458                         {
459                           THROW (ReportedBoundsError);
460                         }
461                       break;
462                     case type29ucd_PREAMBLE_VAL_OFF:
463                       if (tlvlen == 2)
464                         {
465                           proto_tree_add_item (burst_descr_tree,
466                                                hf_docsis_burst_preamble_val_off,
467                                                tvb, pos, tlvlen, FALSE);
468                         }
469                       else
470                         {
471                           THROW (ReportedBoundsError);
472                         }
473                       break;
474                     case type29ucd_FEC:
475                       if (tlvlen == 1)
476                         {
477                           proto_tree_add_item (burst_descr_tree,
478                                                hf_docsis_burst_fec, tvb, pos,
479                                                tlvlen, FALSE);
480                         }
481                       else
482                         {
483                           THROW (ReportedBoundsError);
484                         }
485                       break;
486                     case type29ucd_FEC_CODEWORD:
487                       if (tlvlen == 1)
488                         {
489                           proto_tree_add_item (burst_descr_tree,
490                                                hf_docsis_burst_fec_codeword,
491                                                tvb, pos, tlvlen, FALSE);
492                         }
493                       else
494                         {
495                           THROW (ReportedBoundsError);
496                         }
497                       break;
498                     case type29ucd_SCRAMBLER_SEED:
499                       if (tlvlen == 2)
500                         {
501                           proto_tree_add_item (burst_descr_tree,
502                                                hf_docsis_burst_scrambler_seed,
503                                                tvb, pos, tlvlen, FALSE);
504                         }
505                       else
506                         {
507                           THROW (ReportedBoundsError);
508                         }
509                       break;
510                     case type29ucd_MAX_BURST:
511                       if (tlvlen == 1)
512                         {
513                           proto_tree_add_item (burst_descr_tree,
514                                                hf_docsis_burst_max_burst, tvb,
515                                                pos, tlvlen, FALSE);
516                         }
517                       else
518                         {
519                           THROW (ReportedBoundsError);
520                         }
521                       break;
522                     case type29ucd_GUARD_TIME:
523                       if (tlvlen == 1)
524                         {
525                           proto_tree_add_item (burst_descr_tree,
526                                                hf_docsis_burst_guard_time,
527                                                tvb, pos, tlvlen, FALSE);
528                         }
529                       else
530                         {
531                           THROW (ReportedBoundsError);
532                         }
533                       break;
534                     case type29ucd_LAST_CW_LEN:
535                       if (tlvlen == 1)
536                         {
537                           proto_tree_add_item (burst_descr_tree,
538                                                hf_docsis_burst_last_cw_len,
539                                                tvb, pos, tlvlen, FALSE);
540                         }
541                       else
542                         {
543                           THROW (ReportedBoundsError);
544                         }
545                       break;
546                      case type29ucd_SCRAMBLER_ONOFF:
547                        if (tlvlen == 1)
548                          {
549                             proto_tree_add_item (burst_descr_tree,
550                                                  hf_docsis_burst_scrambler_onoff,
551                                                  tvb, pos, tlvlen, FALSE);
552                          }
553                        else
554                          {
555                             THROW (ReportedBoundsError);
556                          }
557                        break;
558                     }           /* switch(tlvtype) */
559                    pos = pos + tlvlen;
560                 }               /* while (pos < endtlvpos) */
561                break;
562 /* DOCSIS 2.0 Upstream Channel Descriptor */
563              case type29ucd_BURST_DESCR5:
564               it =
565                 proto_tree_add_text (type29ucd_tree, tvb, pos, length,
566                                      "5 Burst Descriptor (Length = %u)",
567                                      length);
568               burst_descr_tree = proto_item_add_subtree (it, ett_burst_descr);
569               proto_tree_add_item (burst_descr_tree, hf_docsis_type29ucd_iuc, tvb,
570                                    pos++, 1, FALSE);
571               endtlvpos = pos + length - 1;
572               while (pos < endtlvpos)
573                 {
574                   tlvtype = tvb_get_guint8 (tvb, pos++);
575                   tlvlen = tvb_get_guint8 (tvb, pos++);
576                   switch (tlvtype)
577                     {
578                     case type29ucd_MODULATION:
579                       if (tlvlen == 1)
580                         {
581                           proto_tree_add_item (burst_descr_tree,
582                                                hf_docsis_burst_mod_type, tvb,
583                                                pos, tlvlen, FALSE);
584                         }
585                       else
586                         {
587                           THROW (ReportedBoundsError);
588                         }
589                       break;
590                     case type29ucd_DIFF_ENCODING:
591                       if (tlvlen == 1)
592                         {
593                           proto_tree_add_item (burst_descr_tree,
594                                                hf_docsis_burst_diff_encoding,
595                                                tvb, pos, tlvlen, FALSE);
596                         }
597                       else
598                         {
599                           THROW (ReportedBoundsError);
600                         }
601                       break;
602                     case type29ucd_PREAMBLE_LEN:
603                       if (tlvlen == 2)
604                         {
605                           proto_tree_add_item (burst_descr_tree,
606                                                hf_docsis_burst_preamble_len,
607                                                tvb, pos, tlvlen, FALSE);
608                         }
609                       else
610                         {
611                           THROW (ReportedBoundsError);
612                         }
613                       break;
614                     case type29ucd_PREAMBLE_VAL_OFF:
615                       if (tlvlen == 2)
616                         {
617                           proto_tree_add_item (burst_descr_tree,
618                                                hf_docsis_burst_preamble_val_off,
619                                                tvb, pos, tlvlen, FALSE);
620                         }
621                       else
622                         {
623                           THROW (ReportedBoundsError);
624                         }
625                       break;
626                     case type29ucd_FEC:
627                       if (tlvlen == 1)
628                         {
629                           proto_tree_add_item (burst_descr_tree,
630                                                hf_docsis_burst_fec, tvb, pos,
631                                                tlvlen, FALSE);
632                         }
633                       else
634                         {
635                           THROW (ReportedBoundsError);
636                         }
637                       break;
638                     case type29ucd_FEC_CODEWORD:
639                       if (tlvlen == 1)
640                         {
641                           proto_tree_add_item (burst_descr_tree,
642                                                hf_docsis_burst_fec_codeword,
643                                                tvb, pos, tlvlen, FALSE);
644                         }
645                       else
646                         {
647                           THROW (ReportedBoundsError);
648                         }
649                       break;
650                     case type29ucd_SCRAMBLER_SEED:
651                       if (tlvlen == 2)
652                         {
653                           proto_tree_add_item (burst_descr_tree,
654                                                hf_docsis_burst_scrambler_seed,
655                                                tvb, pos, tlvlen, FALSE);
656                         }
657                       else
658                         {
659                           THROW (ReportedBoundsError);
660                         }
661                       break;
662                     case type29ucd_MAX_BURST:
663                       if (tlvlen == 1)
664                         {
665                           proto_tree_add_item (burst_descr_tree,
666                                                hf_docsis_burst_max_burst, tvb,
667                                                pos, tlvlen, FALSE);
668                         }
669                       else
670                         {
671                           THROW (ReportedBoundsError);
672                         }
673                       break;
674                     case type29ucd_GUARD_TIME:
675                       if (tlvlen == 1)
676                         {
677                           proto_tree_add_item (burst_descr_tree,
678                                                hf_docsis_burst_guard_time,
679                                                tvb, pos, tlvlen, FALSE);
680                         }
681                       else
682                         {
683                           THROW (ReportedBoundsError);
684                         }
685                       break;
686                     case type29ucd_LAST_CW_LEN:
687                       if (tlvlen == 1)
688                         {
689                           proto_tree_add_item (burst_descr_tree,
690                                                hf_docsis_burst_last_cw_len,
691                                                tvb, pos, tlvlen, FALSE);
692                         }
693                       else
694                         {
695                           THROW (ReportedBoundsError);
696                         }
697                       break;
698                     case type29ucd_SCRAMBLER_ONOFF:
699                       if (tlvlen == 1)
700                         {
701                           proto_tree_add_item (burst_descr_tree,
702                                                hf_docsis_burst_scrambler_onoff,
703                                                tvb, pos, tlvlen, FALSE);
704                         }
705                       else
706                         {
707                           THROW (ReportedBoundsError);
708                         }
709                       break;
710 /* New cases added for DOCSIS 2.0 US Physical Burst Descriptor TLV */
711 /* #define type29ucd_RS_INT_DEPTH 12
712  * #define type29ucd_RS_INT_BLOCK 13
713  * #define type29ucd_PREAMBLE_TYPE 14
714  * #define type29ucd_SCMDA_SCRAMBLER_ONOFF 15
715  * #define type29ucd_SCDMA_CODES_PER_SUBFRAME 16
716  * #define type29ucd_SCDMA_FRAMER_INT_STEP_SIZE 17
717  * #define type29ucd_TCM_ENABLED 18
718  */
719                      case type29ucd_RS_INT_DEPTH:
720                       if (tlvlen == 1)
721                         {
722                           proto_tree_add_item (burst_descr_tree,
723                                                hf_docsis_rs_int_depth,
724                                                tvb, pos, tlvlen, FALSE);
725                         }
726                       else
727                         {
728                           THROW (ReportedBoundsError);
729                         }
730                       break;
731                      case type29ucd_RS_INT_BLOCK:
732                       if (tlvlen == 2)
733                         {
734                           proto_tree_add_item (burst_descr_tree,
735                                                hf_docsis_rs_int_block,
736                                                tvb, pos, tlvlen, FALSE);
737                         }
738                       else
739                         {
740                           THROW (ReportedBoundsError);
741                         }
742                       break;
743                      case type29ucd_PREAMBLE_TYPE:
744                       if (tlvlen == 1)
745                         {
746                           proto_tree_add_item (burst_descr_tree,
747                                                hf_docsis_preamble_type,
748                                                tvb, pos, tlvlen, FALSE);
749                         }
750                       else
751                         {
752                           THROW (ReportedBoundsError);
753                         }
754                       break;
755                      case type29ucd_SCMDA_SCRAMBLER_ONOFF:
756                       if (tlvlen == 1)
757                         {
758                           proto_tree_add_item (burst_descr_tree,
759                                                hf_docsis_scdma_scrambler_onoff,
760                                                tvb, pos, tlvlen, FALSE);
761                         }
762                       else
763                         {
764                           THROW (ReportedBoundsError);
765                         }
766                       break;
767                      case type29ucd_SCDMA_CODES_PER_SUBFRAME:
768                       if (tlvlen == 1)
769                         {
770                           proto_tree_add_item (burst_descr_tree,
771                                                hf_docsis_scdma_codes_per_subframe,
772                                                tvb, pos, tlvlen, FALSE);
773                         }
774                       else
775                         {
776                           THROW (ReportedBoundsError);
777                         }
778                       break;
779                      case type29ucd_SCDMA_FRAMER_INT_STEP_SIZE:
780                       if (tlvlen == 1)
781                         {
782                           proto_tree_add_item (burst_descr_tree,
783                                                hf_docsis_scdma_framer_int_step_size,
784                                                tvb, pos, tlvlen, FALSE);
785                         }
786                       else
787                         {
788                           THROW (ReportedBoundsError);
789                         }
790                       break;
791                      case type29ucd_TCM_ENABLED:
792                       if (tlvlen == 1)
793                         {
794                           proto_tree_add_item (burst_descr_tree,
795                                                hf_docsis_tcm_enabled,
796                                                tvb, pos, tlvlen, FALSE);
797                         }
798                       else
799                         {
800                           THROW (ReportedBoundsError);
801                         }
802                       break;
803 /* End of DOCSIS 2.0 US burst Descriptor Changes */
804                     }           /* switch(tlvtype) */
805                   pos = pos + tlvlen;
806                 }               /* while (pos < endtlvpos) */
807               break;
808             }                   /* switch(type) */
809         }                       /* while (pos < len) */
810     }                           /* if (tree) */
811
812 }
813
814 /* Register the protocol with Wireshark */
815
816 /* this format is require because a script is used to build the C function
817    that calls all the protocol registration.
818 */
819
820
821 void
822 proto_register_docsis_type29ucd (void)
823 {
824
825 /* Setup list of header fields  See Section 1.6.1 for details*/
826   static hf_register_info hf[] = {
827     {&hf_docsis_type29ucd_upstream_chid,
828      {"Upstream Channel ID", "docsis_type29ucd.upchid",
829       FT_UINT8, BASE_DEC, NULL, 0x0,
830       NULL, HFILL}
831      },
832     {&hf_docsis_type29ucd_config_ch_cnt,
833      {"Config Change Count", "docsis_type29ucd.confcngcnt",
834       FT_UINT8, BASE_DEC, NULL, 0x0,
835       "Configuration Change Count", HFILL}
836      },
837     {&hf_docsis_type29ucd_mini_slot_size,
838      {"Mini Slot Size (6.25us TimeTicks)", "docsis_type29ucd.mslotsize",
839       FT_UINT8, BASE_DEC, NULL, 0x0,
840       NULL, HFILL}
841      },
842     {&hf_docsis_type29ucd_down_chid,
843      {"Downstream Channel ID", "docsis_type29ucd.downchid",
844       FT_UINT8, BASE_DEC, NULL, 0x0,
845       "Management Message", HFILL}
846      },
847     {&hf_docsis_type29ucd_symbol_rate,
848      {"1 Symbol Rate (ksym/sec)", "docsis_type29ucd.symrate",
849       FT_UINT8, BASE_DEC, NULL, 0x0,
850       "Symbol Rate", HFILL}
851      },
852     {&hf_docsis_type29ucd_frequency,
853      {"2 Frequency (Hz)", "docsis_type29ucd.freq",
854       FT_UINT32, BASE_DEC, NULL, 0x0,
855       "Upstream Center Frequency", HFILL}
856      },
857     {&hf_docsis_type29ucd_preamble_pat,
858      {"3 Preamble Pattern", "docsis_type29ucd.preamble",
859       FT_BYTES, BASE_NONE, NULL, 0x0,
860       "Preamble Superstring", HFILL}
861      },
862     {&hf_docsis_type29ucd_iuc,
863      {"Interval Usage Code", "docsis_type29ucd.iuc",
864       FT_UINT8, BASE_DEC, VALS (iuc_vals2), 0x0,
865       NULL, HFILL}
866      },
867     {&hf_docsis_burst_mod_type,
868      {"1 Modulation Type", "docsis_type29ucd.burst.modtype",
869       FT_UINT8, BASE_DEC, VALS (mod_vals2), 0x0,
870       "Modulation Type", HFILL}
871      },
872     {&hf_docsis_burst_diff_encoding,
873      {"2 Differential Encoding", "docsis_type29ucd.burst.diffenc",
874       FT_UINT8, BASE_DEC, VALS (on_off_vals), 0x0,
875       "Differential Encoding", HFILL}
876      },
877     {&hf_docsis_burst_preamble_len,
878      {"3 Preamble Length (Bits)", "docsis_type29ucd.burst.preamble_len",
879       FT_UINT16, BASE_DEC, NULL, 0x0,
880       "Preamble Length (Bits)", HFILL}
881      },
882     {&hf_docsis_burst_preamble_val_off,
883      {"4 Preamble Offset (Bits)", "docsis_type29ucd.burst.preamble_off",
884       FT_UINT16, BASE_DEC, NULL, 0x0,
885       "Preamble Offset (Bits)", HFILL}
886      },
887     {&hf_docsis_burst_fec,
888      {"5 FEC (T)", "docsis_type29ucd.burst.fec",
889       FT_UINT8, BASE_DEC, NULL, 0x0,
890       "FEC (T) Codeword Parity Bits = 2^T", HFILL}
891      },
892     {&hf_docsis_burst_fec_codeword,
893      {"6 FEC Codeword Info bytes (k)", "docsis_type29ucd.burst.fec_codeword",
894       FT_UINT8, BASE_DEC, NULL, 0x0,
895       "FEC Codeword Info Bytes (k)", HFILL}
896      },
897     {&hf_docsis_burst_scrambler_seed,
898      {"7 Scrambler Seed", "docsis_type29ucd.burst.scrambler_seed",
899       FT_UINT16, BASE_HEX, NULL, 0x0,
900       "Burst Descriptor", HFILL}
901      },
902     {&hf_docsis_burst_max_burst,
903      {"8 Max Burst Size (Minislots)", "docsis_type29ucd.burst.maxburst",
904       FT_UINT8, BASE_DEC, NULL, 0x0,
905       "Max Burst Size (Minislots)", HFILL}
906      },
907     {&hf_docsis_burst_guard_time,
908      {"9 Guard Time Size (Symbol Times)", "docsis_type29ucd.burst.guardtime",
909       FT_UINT8, BASE_DEC, NULL, 0x0,
910       "Guard Time Size", HFILL}
911      },
912     {&hf_docsis_burst_last_cw_len,
913      {"10 Last Codeword Length", "docsis_type29ucd.burst.last_cw_len",
914       FT_UINT8, BASE_DEC, VALS (last_cw_len_vals), 0x0,
915       "Last Codeword Length", HFILL}
916      },
917     {&hf_docsis_burst_scrambler_onoff,
918      {"11 Scrambler On/Off", "docsis_type29ucd.burst.scrambleronoff",
919       FT_UINT8, BASE_DEC, VALS (on_off_vals), 0x0,
920       "Scrambler On/Off", HFILL}
921      },
922 /* DOCSIS 2.0 UCD TLV definitions
923  *  * #define type29ucd_EXT_PREAMBLE 6
924  *  * #define type29ucd_SCDMA_MODE_ENABLE 7
925  *  * #define type29ucd_SCDMA_SPREADING_INTERVAL 8
926  *  * #define type29ucd_SCDMA_CODES_PER_MINI_SLOT 9
927  *  * #define type29ucd_SCDMA_ACTIVE_CODES 10
928  *  * #define type29ucd_SCDMA_CODE_HOPPING_SEED 11
929  *  * #define type29ucd_SCDMA_US_RATIO_NUM 12
930  *  * #define type29ucd_SCDMA_US_RATIO_DENOM 13
931  *  * #define type29ucd_SCDMA_TIMESTAMP_SNAPSHOT 14
932  *  * #define type29ucd_MAINTAIN_POWER_SPECTRAL_DENSITY 15
933  *  * #define type29ucd_RANGING_REQUIRED 16
934  *  */
935     {&hf_docsis_type29ucd_ext_preamble,
936      {"6 Extended Preamble Pattern", "docsis_type29ucd.extpreamble",
937       FT_BYTES, BASE_NONE, NULL, 0x0,
938       "Extended Preamble Pattern", HFILL}
939      },
940     {&hf_docsis_type29ucd_scdma_mode_enable,
941      {"7 SCDMA Mode Enable", "docsis_type29ucd.scdmaenable",
942       FT_BYTES, BASE_NONE, NULL, 0x0,
943       "SCDMA Mode Enable", HFILL}
944      },
945     {&hf_docsis_type29ucd_scdma_spreading_interval,
946      {"8 SCDMA Spreading Interval", "docsis_type29ucd.scdmaspreadinginterval",
947       FT_BYTES, BASE_NONE, NULL, 0x0,
948       "SCDMA Spreading Interval", HFILL}
949      },
950     {&hf_docsis_type29ucd_scdma_codes_per_mini_slot,
951      {"9 SCDMA Codes per mini slot", "docsis_type29ucd.scdmacodesperminislot",
952       FT_BYTES, BASE_NONE, NULL, 0x0,
953       "SCDMA Codes per mini slot", HFILL}
954      },
955     {&hf_docsis_type29ucd_scdma_active_codes,
956      {"10 SCDMA Active Codes", "docsis_type29ucd.scdmaactivecodes",
957       FT_BYTES, BASE_NONE, NULL, 0x0,
958       "SCDMA Active Codes", HFILL}
959      },
960     {&hf_docsis_type29ucd_scdma_code_hopping_seed,
961      {"11 SCDMA Code Hopping Seed", "docsis_type29ucd.scdmacodehoppingseed",
962       FT_BYTES, BASE_NONE, NULL, 0x0,
963       "SCDMA Code Hopping Seed", HFILL}
964      },
965     {&hf_docsis_type29ucd_scdma_us_ratio_num,
966      {"12 SCDMA US Ratio Numerator", "docsis_type29ucd.scdmausrationum",
967       FT_BYTES, BASE_NONE, NULL, 0x0,
968       "SCDMA US Ratio Numerator", HFILL}
969      },
970     {&hf_docsis_type29ucd_scdma_us_ratio_denom,
971      {"13 SCDMA US Ratio Denominator", "docsis_type29ucd.scdmausratiodenom",
972       FT_BYTES, BASE_NONE, NULL, 0x0,
973       "SCDMA US Ratio Denominator", HFILL}
974      },
975     {&hf_docsis_type29ucd_scdma_timestamp_snapshot,
976      {"14 SCDMA Timestamp Snapshot", "docsis_type29ucd.scdmatimestamp",
977       FT_BYTES, BASE_NONE, NULL, 0x0,
978       "SCDMA Timestamp Snapshot", HFILL}
979      },
980     {&hf_docsis_type29ucd_maintain_power_spectral_density,
981      {"15 Maintain power spectral density", "docsis_type29ucd.maintainpowerspectraldensity",
982       FT_BYTES, BASE_NONE, NULL, 0x0,
983       "Maintain power spectral density", HFILL}
984      },
985     {&hf_docsis_type29ucd_ranging_required,
986      {"16 Ranging Required", "docsis_type29ucd.rangingrequired",
987       FT_BYTES, BASE_NONE, NULL, 0x0,
988       "Ranging Required", HFILL}
989      },
990 /* #define type29ucd_RS_INT_DEPTH 12
991  * #define type29ucd_RS_INT_BLOCK 13
992  * #define type29ucd_PREAMBLE_TYPE 14
993  * #define type29ucd_SCMDA_SCRAMBLER_ONOFF 15
994  * #define type29ucd_SCDMA_CODES_PER_SUBFRAME 16
995  * #define type29ucd_SCDMA_FRAMER_INT_STEP_SIZE 17
996  * #define type29ucd_TCM_ENABLED 18
997  */
998     {&hf_docsis_rs_int_depth,
999      {"12 Scrambler On/Off", "docsis_type29ucd.burst.rsintdepth",
1000       FT_UINT8, BASE_DEC, NULL, 0x0,
1001       "R-S Interleaver Depth", HFILL}
1002      },
1003     {&hf_docsis_rs_int_block,
1004      {"13 Scrambler On/Off", "docsis_type29ucd.burst.rsintblock",
1005       FT_UINT8, BASE_DEC, NULL, 0x0,
1006       "R-S Interleaver Block", HFILL}
1007      },
1008     {&hf_docsis_preamble_type,
1009      {"14 Scrambler On/Off", "docsis_type29ucd.burst.preambletype",
1010       FT_UINT8, BASE_DEC, NULL, 0x0,
1011       "Preamble Type", HFILL}
1012      },
1013     {&hf_docsis_scdma_scrambler_onoff,
1014      {"15 Scrambler On/Off", "docsis_type29ucd.burst.scdmascrambleronoff",
1015       FT_UINT8, BASE_DEC, VALS (on_off_vals), 0x0,
1016       "SCDMA Scrambler On/Off", HFILL}
1017      },
1018     {&hf_docsis_scdma_codes_per_subframe,
1019      {"16 Scrambler On/Off", "docsis_type29ucd.burst.scdmacodespersubframe",
1020       FT_UINT8, BASE_DEC, NULL, 0x0,
1021       "SCDMA Codes per Subframe", HFILL}
1022      },
1023     {&hf_docsis_scdma_framer_int_step_size,
1024      {"17 Scrambler On/Off", "docsis_type29ucd.burst.scdmaframerintstepsize",
1025       FT_UINT8, BASE_DEC, NULL, 0x0,
1026       "SCDMA Framer Interleaving Step Size", HFILL}
1027      },
1028     {&hf_docsis_tcm_enabled,
1029      {"18 Scrambler On/Off", "docsis_type29ucd.burst.tcmenabled",
1030       FT_UINT8, BASE_DEC, VALS (on_off_vals), 0x0,
1031       "TCM Enabled", HFILL}
1032      },
1033   };
1034
1035 /* Setup protocol subtree array */
1036   static gint *ett[] = {
1037     &ett_docsis_type29ucd,
1038     &ett_burst_descr,
1039   };
1040
1041 /* Register the protocol name and description */
1042   proto_docsis_type29ucd =
1043     proto_register_protocol ("DOCSIS Upstream Channel Descriptor Type 29",
1044                              "DOCSIS type29ucd", "docsis_type29ucd");
1045
1046 /* Required function calls to register the header fields and subtrees used */
1047   proto_register_field_array (proto_docsis_type29ucd, hf, array_length (hf));
1048   proto_register_subtree_array (ett, array_length (ett));
1049
1050   register_dissector ("docsis_type29ucd", dissect_type29ucd, proto_docsis_type29ucd);
1051 }
1052
1053
1054 /* If this dissector uses sub-dissector registration add a registration routine.
1055    This format is required because a script is used to find these routines and
1056    create the code that calls these routines.
1057 */
1058 void
1059 proto_reg_handoff_docsis_type29ucd (void)
1060 {
1061   dissector_handle_t docsis_type29ucd_handle;
1062
1063   docsis_type29ucd_handle = find_dissector ("docsis_type29ucd");
1064   dissector_add_uint ("docsis_mgmt", 0x1D, docsis_type29ucd_handle);
1065
1066 }