Use ENC_NA as proto_tree_add_item() encoding arg for FT_ETHER hf[] field type.
[obnox/wireshark/wip.git] / plugins / docsis / packet-dcd.c
1 /* packet-dcd.c
2  * Routines for DCD Message dissection
3  * Copyright 2004, Darryl Hymel <darryl.hymel[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 DCD_DOWN_CLASSIFIER 23
33 #define DCD_DSG_RULE 50
34 #define DCD_DSG_CONFIG 51
35
36 /* Define Downstrean Classifier subtypes
37  * These are subtype of DCD_DOWN_CLASSIFIER (23)
38  */
39
40 #define DCD_CFR_ID 2
41 #define DCD_CFR_RULE_PRI 5
42 #define DCD_CFR_IP_CLASSIFIER 9
43
44 /* Define IP Classifier sub-subtypes
45  * These are subtypes of DCD_CFR_IP_CLASSIFIER (23.9)
46  */
47 #define DCD_CFR_IP_SOURCE_ADDR 3
48 #define DCD_CFR_IP_SOURCE_MASK 4
49 #define DCD_CFR_IP_DEST_ADDR 5
50 #define DCD_CFR_IP_DEST_MASK 6
51 #define DCD_CFR_TCPUDP_SRCPORT_START 7
52 #define DCD_CFR_TCPUDP_SRCPORT_END 8
53 #define DCD_CFR_TCPUDP_DSTPORT_START 9
54 #define DCD_CFR_TCPUDP_DSTPORT_END 10
55
56 /* Define DSG Rule subtypes
57  * These are subtype of DCD_DSG_RULE (50)
58  */
59
60 #define DCD_RULE_ID 1
61 #define DCD_RULE_PRI 2
62 #define DCD_RULE_UCID_RNG 3
63 #define DCD_RULE_CLIENT_ID 4
64 #define DCD_RULE_TUNL_ADDR 5
65 #define DCD_RULE_CFR_ID 6
66 #define DCD_RULE_VENDOR_SPEC 43
67 /* Define DSG Rule Client ID sub-subtypes
68  * These are subtypes of DCD_RULE_CLIENT_ID (50.4)
69  */
70 #define DCD_CLID_BCAST_ID 1
71 #define DCD_CLID_KNOWN_MAC_ADDR 2
72 #define DCD_CLID_CA_SYS_ID 3
73 #define DCD_CLID_APP_ID 4
74
75 /* Define DSG Configuration subtypes
76  * These are subtype of DCD_DSG_CONFIG (51)
77  */
78
79 #define DCD_CFG_CHAN_LST 1
80 #define DCD_CFG_TDSG1 2
81 #define DCD_CFG_TDSG2 3
82 #define DCD_CFG_TDSG3 4
83 #define DCD_CFG_TDSG4 5
84 #define DCD_CFG_VENDOR_SPEC 43
85
86 /* Initialize the protocol and registered fields */
87 static int proto_docsis_dcd = -1;
88
89 static int hf_docsis_dcd_config_ch_cnt = -1;
90 static int hf_docsis_dcd_num_of_frag = -1;
91 static int hf_docsis_dcd_frag_sequence_num = -1;
92 static int hf_docsis_dcd_cfr_id = -1;
93 static int hf_docsis_dcd_cfr_rule_pri = -1;
94 static int hf_docsis_dcd_cfr_ip_source_addr = -1;
95 static int hf_docsis_dcd_cfr_ip_source_mask = -1;
96 static int hf_docsis_dcd_cfr_ip_dest_addr = -1;
97 static int hf_docsis_dcd_cfr_ip_dest_mask = -1;
98 static int hf_docsis_dcd_cfr_tcpudp_srcport_start = -1;
99 static int hf_docsis_dcd_cfr_tcpudp_srcport_end = -1;
100 static int hf_docsis_dcd_cfr_tcpudp_dstport_start = -1;
101 static int hf_docsis_dcd_cfr_tcpudp_dstport_end = -1;
102 static int hf_docsis_dcd_rule_id = -1;
103 static int hf_docsis_dcd_rule_pri = -1;
104 static int hf_docsis_dcd_rule_ucid_list = -1;
105 static int hf_docsis_dcd_clid_known_mac_addr = -1;
106 static int hf_docsis_dcd_clid_ca_sys_id = -1;
107 static int hf_docsis_dcd_clid_app_id = -1;
108 static int hf_docsis_dcd_rule_tunl_addr = -1;
109 static int hf_docsis_dcd_rule_cfr_id = -1;
110 static int hf_docsis_dcd_rule_vendor_spec = -1;
111 static int hf_docsis_dcd_cfg_chan = -1;
112 static int hf_docsis_dcd_cfg_tdsg1 = -1;
113 static int hf_docsis_dcd_cfg_tdsg2 = -1;
114 static int hf_docsis_dcd_cfg_tdsg3 = -1;
115 static int hf_docsis_dcd_cfg_tdsg4 = -1;
116 static int hf_docsis_dcd_cfg_vendor_spec = -1;
117
118 /* Initialize the subtree pointers */
119 static gint ett_docsis_dcd = -1;
120 static gint ett_docsis_dcd_cfr = -1;
121 static gint ett_docsis_dcd_cfr_ip = -1;
122 static gint ett_docsis_dcd_rule = -1;
123 static gint ett_docsis_dcd_clid = -1;
124 static gint ett_docsis_dcd_cfg = -1;
125
126 /* Code to actually dissect the packets */
127 static void
128 dissect_dcd_dsg_cfg (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
129 {
130   guint8 type, length;
131   proto_item *dcd_item;
132   proto_tree *dcd_tree;
133   int pos;
134    
135   pos = start;
136   dcd_item = proto_tree_add_text ( tree, tvb, start, len, "51 DCD DSG Config Encodings (Length = %u)", len);
137   dcd_tree = proto_item_add_subtree ( dcd_item , ett_docsis_dcd_cfg);
138   
139   while ( pos < ( start + len) ) 
140     {
141         type = tvb_get_guint8 (tvb, pos++);
142         length = tvb_get_guint8 (tvb, pos++);
143         
144         switch (type)
145           {
146             case DCD_CFG_CHAN_LST:
147               if (length == 4)
148                 {
149                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfg_chan, tvb,
150                                        pos, length, ENC_BIG_ENDIAN);
151                 }
152               else
153                 {
154                   THROW (ReportedBoundsError);
155                 }
156               break;
157             case DCD_CFG_TDSG1:
158               if (length == 2)
159                 {
160                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfg_tdsg1, tvb,
161                                    pos, length, ENC_BIG_ENDIAN);
162                 }
163               else 
164                 {
165                   THROW (ReportedBoundsError);
166                 }
167               break;
168             case DCD_CFG_TDSG2:
169               if (length == 2)
170                 {
171                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfg_tdsg2, tvb,
172                                    pos, length, ENC_BIG_ENDIAN);
173                 }
174               else 
175                 {
176                   THROW (ReportedBoundsError);
177                 }
178               break;
179             case DCD_CFG_TDSG3:
180               if (length == 2)
181                 {
182                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfg_tdsg3, tvb,
183                                    pos, length, ENC_BIG_ENDIAN);
184                 }
185               else 
186                 {
187                   THROW (ReportedBoundsError);
188                 }
189               break;
190             case DCD_CFG_TDSG4:
191               if (length == 2)
192                 {
193                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfg_tdsg4, tvb,
194                                    pos, length, ENC_BIG_ENDIAN);
195                 }
196               else 
197                 {
198                   THROW (ReportedBoundsError);
199                 }
200               break;
201             case DCD_CFG_VENDOR_SPEC:
202                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfg_vendor_spec, tvb,
203                                    pos, length, ENC_NA);
204               break;
205
206             }
207           pos = pos + length;
208       }
209 }
210 static void
211 dissect_dcd_down_classifier_ip (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
212 {
213   guint8 type, length;
214   proto_item *dcd_item;
215   proto_tree *dcd_tree;
216   int pos;
217    
218   pos = start;
219   dcd_item = proto_tree_add_text ( tree, tvb, start, len, "23.9 DCD_CFR_IP Encodings (Length = %u)", len);
220   dcd_tree = proto_item_add_subtree ( dcd_item , ett_docsis_dcd_cfr_ip);
221   
222   while ( pos < ( start + len) ) 
223     {
224         type = tvb_get_guint8 (tvb, pos++);
225         length = tvb_get_guint8 (tvb, pos++);
226         
227         switch (type)
228           {
229             case DCD_CFR_IP_SOURCE_ADDR:
230               if (length == 4)
231                 {
232                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_ip_source_addr, tvb,
233                                        pos, length, ENC_BIG_ENDIAN);
234                 }
235               else
236                 {
237                   THROW (ReportedBoundsError);
238                 }
239               break;
240             case DCD_CFR_IP_SOURCE_MASK:
241               if (length == 4)
242                 {
243                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_ip_source_mask, tvb,
244                                        pos, length, ENC_BIG_ENDIAN);
245                 }
246               else
247                 {
248                   THROW (ReportedBoundsError);
249                 }
250               break;
251             case DCD_CFR_IP_DEST_ADDR:
252               if (length == 4)
253                 {
254                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_ip_dest_addr, tvb,
255                                        pos, length, ENC_BIG_ENDIAN);
256                 }
257               else
258                 {
259                   THROW (ReportedBoundsError);
260                 }
261                 break;
262             case DCD_CFR_IP_DEST_MASK:
263               if (length == 4)
264                 {
265                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_ip_dest_mask, tvb,
266                                        pos, length, ENC_BIG_ENDIAN);
267                 }
268               else
269                 {
270                   THROW (ReportedBoundsError);
271                 }
272                 break;
273             case DCD_CFR_TCPUDP_SRCPORT_START:
274               if (length == 2)
275                 {
276                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_tcpudp_srcport_start, tvb,
277                                        pos, length, ENC_BIG_ENDIAN);
278                 }
279               else
280                 {
281                   THROW (ReportedBoundsError);
282                 }
283                 break;
284             case DCD_CFR_TCPUDP_SRCPORT_END:
285               if (length == 2)
286                 {
287                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_tcpudp_srcport_end, tvb,
288                                        pos, length, ENC_BIG_ENDIAN);
289                 }
290               else
291                 {
292                   THROW (ReportedBoundsError);
293                 }
294                 break;
295             case DCD_CFR_TCPUDP_DSTPORT_START:
296               if (length == 2)
297                 {
298                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_tcpudp_dstport_start, tvb,
299                                        pos, length, ENC_BIG_ENDIAN);
300                 }
301               else
302                 {
303                   THROW (ReportedBoundsError);
304                 }
305                 break;
306             case DCD_CFR_TCPUDP_DSTPORT_END:
307               if (length == 2)
308                 {
309                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_tcpudp_dstport_end, tvb,
310                                        pos, length, ENC_BIG_ENDIAN);
311                 }
312               else
313                 {
314                   THROW (ReportedBoundsError);
315                 }
316                 break;
317             }
318           pos = pos + length;
319       }
320 }
321 static void
322 dissect_dcd_clid (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
323 {
324   guint8 type, length;
325   proto_item *dcd_item;
326   proto_tree *dcd_tree;
327   int pos;
328    
329   pos = start;
330   dcd_item = proto_tree_add_text ( tree, tvb, start, len, "50.4 DCD Rule ClientID Encodings (Length = %u)", len);
331   dcd_tree = proto_item_add_subtree ( dcd_item , ett_docsis_dcd_clid);
332   
333   while ( pos < ( start + len) ) 
334     {
335         type = tvb_get_guint8 (tvb, pos++);
336         length = tvb_get_guint8 (tvb, pos++);
337         
338         switch (type)
339           {
340             case DCD_CLID_KNOWN_MAC_ADDR:
341               if (length == 6)
342                 {
343                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_clid_known_mac_addr, tvb,
344                                        pos, length, ENC_NA);
345                 }
346               else
347                 {
348                   THROW (ReportedBoundsError);
349                 }
350               break;
351             case DCD_CLID_CA_SYS_ID:
352               if (length == 2)
353                 {
354                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_clid_ca_sys_id, tvb,
355                                        pos, length, ENC_BIG_ENDIAN);
356                 }
357               else
358                 {
359                   THROW (ReportedBoundsError);
360                 }
361               break;
362             case DCD_CLID_APP_ID:
363               if (length == 2)
364                 {
365                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_clid_app_id, tvb,
366                                        pos, length, ENC_BIG_ENDIAN);
367                 }
368               else
369                 {
370                   THROW (ReportedBoundsError);
371                 }
372                 break;
373             }
374           pos = pos + length;
375       }
376 }
377 static void
378 dissect_dcd_dsg_rule (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
379 {
380   guint8 type, length;
381   proto_item *dcd_item;
382   proto_tree *dcd_tree;
383   int pos;
384    
385   pos = start;
386   dcd_item = proto_tree_add_text ( tree, tvb, start, len, "50 DCD DSG Rule Encodings (Length = %u)", len);
387   dcd_tree = proto_item_add_subtree ( dcd_item , ett_docsis_dcd_rule);
388   
389   while ( pos < ( start + len) ) 
390     {
391         type = tvb_get_guint8 (tvb, pos++);
392         length = tvb_get_guint8 (tvb, pos++);
393         
394         switch (type)
395           {
396             case DCD_RULE_ID:
397               if (length == 1)
398                 {
399                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_rule_id, tvb,
400                                        pos, length, ENC_BIG_ENDIAN);
401                 }
402               else
403                 {
404                   THROW (ReportedBoundsError);
405                 }
406               break;
407             case DCD_RULE_PRI:
408               if (length == 1)
409                 {
410                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_rule_pri, tvb,
411                                    pos, length, ENC_BIG_ENDIAN);
412                 }
413               else 
414                 {
415                   THROW (ReportedBoundsError);
416                 }
417               break;
418             case DCD_RULE_UCID_RNG:
419                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_rule_ucid_list, tvb,
420                                    pos, length, ENC_NA);
421               break;
422             case DCD_RULE_CLIENT_ID:
423               dissect_dcd_clid (tvb , dcd_tree , pos , length );
424               break;
425             case DCD_RULE_TUNL_ADDR:
426               if (length == 6)
427                 {
428                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_rule_tunl_addr, tvb,
429                                    pos, length, ENC_NA);
430                 }
431               else 
432                 {
433                   THROW (ReportedBoundsError);
434                 }
435               break;
436             case DCD_RULE_CFR_ID:
437               if (length == 2)
438                 {
439                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_rule_cfr_id, tvb,
440                                    pos, length, ENC_BIG_ENDIAN);
441                 }
442               else 
443                 {
444                   THROW (ReportedBoundsError);
445                 }
446               break;
447             case DCD_RULE_VENDOR_SPEC:
448                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_rule_vendor_spec, tvb,
449                                    pos, length, ENC_NA);
450               break;
451
452             }
453           pos = pos + length;
454       }
455 }
456 static void
457 dissect_dcd_down_classifier (tvbuff_t * tvb, proto_tree * tree, int start, guint16 len)
458 {
459   guint8 type, length;
460   proto_item *dcd_item;
461   proto_tree *dcd_tree;
462   int pos;
463    
464   pos = start;
465   dcd_item = proto_tree_add_text ( tree, tvb, start, len, "23 DCD_CFR Encodings (Length = %u)", len);
466   dcd_tree = proto_item_add_subtree ( dcd_item , ett_docsis_dcd_cfr);
467   
468   while ( pos < ( start + len) ) 
469     {
470         type = tvb_get_guint8 (tvb, pos++);
471         length = tvb_get_guint8 (tvb, pos++);
472         
473         switch (type)
474           {
475             case DCD_CFR_ID:
476               if (length == 2)
477                 {
478                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_id, tvb,
479                                        pos, length, ENC_BIG_ENDIAN);
480                 }
481               else
482                 {
483                   THROW (ReportedBoundsError);
484                 }
485               break;
486             case DCD_CFR_RULE_PRI:
487               if (length == 1)
488                 {
489                   proto_tree_add_item (dcd_tree, hf_docsis_dcd_cfr_rule_pri, tvb,
490                                    pos, length, ENC_BIG_ENDIAN);
491                 }
492               else 
493                 {
494                   THROW (ReportedBoundsError);
495                 }
496               break;
497             case DCD_CFR_IP_CLASSIFIER:
498               dissect_dcd_down_classifier_ip (tvb , dcd_tree , pos , length );
499               break;
500
501             }
502           pos = pos + length;
503       }
504 }
505 static void
506 dissect_dcd (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
507 {
508   guint16 pos;
509   guint8 type, length;
510   proto_tree *dcd_tree;
511   proto_item *dcd_item;
512   guint16 len;
513
514   len = tvb_length_remaining (tvb, 0);
515
516   col_set_str(pinfo->cinfo, COL_INFO, "DCD Message: ");
517
518   if (tree)
519     {
520       dcd_item =
521         proto_tree_add_protocol_format (tree, proto_docsis_dcd, tvb, 0,
522                                         tvb_length_remaining (tvb, 0),
523                                         "DCD Message");
524       dcd_tree = proto_item_add_subtree (dcd_item, ett_docsis_dcd);
525       proto_tree_add_item (dcd_tree, hf_docsis_dcd_config_ch_cnt, tvb, 0, 1, ENC_BIG_ENDIAN);
526       proto_tree_add_item (dcd_tree, hf_docsis_dcd_num_of_frag, tvb, 1, 1, ENC_BIG_ENDIAN);
527       proto_tree_add_item (dcd_tree, hf_docsis_dcd_frag_sequence_num, tvb, 2, 1, ENC_BIG_ENDIAN);
528
529       pos = 3;
530       while (pos < len)
531         {
532           type = tvb_get_guint8 (tvb, pos++);
533           length = tvb_get_guint8 (tvb, pos++);
534           switch (type)
535             {
536             case DCD_DOWN_CLASSIFIER:
537               dissect_dcd_down_classifier (tvb , dcd_tree , pos , length );
538               break;
539             case DCD_DSG_RULE:
540               dissect_dcd_dsg_rule (tvb , dcd_tree , pos , length );
541               break;
542             case DCD_DSG_CONFIG:
543               dissect_dcd_dsg_cfg (tvb , dcd_tree , pos , length );
544               break;
545             }                   /* switch(type) */
546           pos = pos + length;
547         }                       /* while (pos < len) */
548     }                           /* if (tree) */
549
550 }
551 /* Register the protocol with Wireshark */
552
553 /* this format is require because a script is used to build the C function
554    that calls all the protocol registration.
555 */
556
557
558 void
559 proto_register_docsis_dcd (void)
560 {
561 /* Setup list of header fields  See Section 1.6.1 for details*/
562   static hf_register_info hf[] = {
563     {&hf_docsis_dcd_config_ch_cnt,
564       {
565       "Configuration Change Count", 
566       "docsis_dcd.config_ch_cnt",
567       FT_UINT8, BASE_DEC, NULL, 0x0,
568       NULL, 
569       HFILL
570       }
571     },
572     {&hf_docsis_dcd_num_of_frag,
573       {
574       "Number of Fragments", 
575       "docsis_dcd.num_of_frag",
576       FT_UINT8, BASE_DEC, NULL, 0x0,
577       NULL, 
578       HFILL
579       }
580     },
581     {&hf_docsis_dcd_frag_sequence_num,
582       {
583       "Fragment Sequence Number", 
584       "docsis_dcd.frag_sequence_num",
585       FT_UINT8, BASE_DEC, NULL, 0x0,
586       NULL, 
587       HFILL
588       }
589     },
590     {&hf_docsis_dcd_cfr_id,
591       {
592       "Downstream Classifier Id", 
593       "docsis_dcd.cfr_id",
594       FT_UINT16, BASE_DEC, NULL, 0x0,
595       NULL, 
596       HFILL
597       }
598     },
599     {&hf_docsis_dcd_cfr_rule_pri,
600       {
601       "Downstream Classifier Rule Priority", 
602       "docsis_dcd.cfr_rule_pri",
603       FT_UINT8, BASE_DEC, NULL, 0x0,
604       NULL, 
605       HFILL
606       }
607     },
608     {&hf_docsis_dcd_cfr_ip_source_addr,
609       {
610       "Downstream Classifier IP Source Address", 
611       "docsis_dcd.cfr_ip_source_addr",
612       FT_IPv4, BASE_NONE, NULL, 0x0,
613       NULL, 
614       HFILL
615       }
616     },
617     {&hf_docsis_dcd_cfr_ip_source_mask,
618       {
619       "Downstream Classifier IP Source Mask", 
620       "docsis_dcd.cfr_ip_source_mask",
621       FT_IPv4, BASE_NONE, NULL, 0x0,
622       NULL, 
623       HFILL
624       }
625     },
626     {&hf_docsis_dcd_cfr_ip_dest_addr,
627       {
628       "Downstream Classifier IP Destination Address", 
629       "docsis_dcd.cfr_ip_dest_addr",
630       FT_IPv4, BASE_NONE, NULL, 0x0,
631       NULL, 
632       HFILL
633       }
634     },
635     {&hf_docsis_dcd_cfr_ip_dest_mask,
636       {
637       "Downstream Classifier IP Destination Mask", 
638       "docsis_dcd.cfr_ip_dest_mask",
639       FT_IPv4, BASE_NONE, NULL, 0x0,
640       "Downstream Classifier IP Destination Address", 
641       HFILL
642       }
643     },
644     {&hf_docsis_dcd_cfr_tcpudp_srcport_start,
645       {
646       "Downstream Classifier IP TCP/UDP Source Port Start", 
647       "docsis_dcd.cfr_ip_tcpudp_srcport_start",
648       FT_UINT16, BASE_DEC, NULL, 0x0,
649       NULL, 
650       HFILL
651       }
652     },
653     {&hf_docsis_dcd_cfr_tcpudp_srcport_end,
654       {
655       "Downstream Classifier IP TCP/UDP Source Port End", 
656       "docsis_dcd.cfr_ip_tcpudp_srcport_end",
657       FT_UINT16, BASE_DEC, NULL, 0x0,
658       NULL, 
659       HFILL
660       }
661     },
662     {&hf_docsis_dcd_cfr_tcpudp_dstport_start,
663       {
664       "Downstream Classifier IP TCP/UDP Destination Port Start", 
665       "docsis_dcd.cfr_ip_tcpudp_dstport_start",
666       FT_UINT16, BASE_DEC, NULL, 0x0,
667       NULL, 
668       HFILL
669       }
670     },
671     {&hf_docsis_dcd_cfr_tcpudp_dstport_end,
672       {
673       "Downstream Classifier IP TCP/UDP Destination Port End", 
674       "docsis_dcd.cfr_ip_tcpudp_dstport_end",
675       FT_UINT16, BASE_DEC, NULL, 0x0,
676       NULL, 
677       HFILL
678       }
679     },
680     {&hf_docsis_dcd_rule_id,
681       {
682       "DSG Rule Id", 
683       "docsis_dcd.rule_id",
684       FT_UINT8, BASE_DEC, NULL, 0x0,
685       NULL, 
686       HFILL
687       }
688     },
689     {&hf_docsis_dcd_rule_pri,
690       {
691       "DSG Rule Priority", 
692       "docsis_dcd.rule_pri",
693       FT_UINT8, BASE_DEC, NULL, 0x0,
694       NULL, 
695       HFILL
696       }
697     },
698     {&hf_docsis_dcd_rule_ucid_list,
699       {
700       "DSG Rule UCID Range", 
701       "docsis_dcd.rule_ucid_list",
702       FT_BYTES, BASE_NONE, NULL, 0x0,
703       NULL, 
704       HFILL
705       }
706     },
707     {&hf_docsis_dcd_clid_known_mac_addr,
708       {
709       "DSG Rule Client ID Known MAC Address", 
710       "docsis_dcd.clid_known_mac_addr",
711       FT_ETHER, BASE_NONE, NULL, 0x0,
712       NULL, 
713       HFILL
714       }
715     },
716     {&hf_docsis_dcd_clid_ca_sys_id,
717       {
718       "DSG Rule Client ID CA System ID", 
719       "docsis_dcd.clid_ca_sys_id",
720       FT_UINT16, BASE_DEC, NULL, 0x0,
721       NULL, 
722       HFILL
723       }
724     },
725     {&hf_docsis_dcd_clid_app_id,
726       {
727       "DSG Rule Client ID Application ID", 
728       "docsis_dcd.clid_app_id",
729       FT_UINT16, BASE_DEC, NULL, 0x0,
730       NULL, 
731       HFILL
732       }
733     },
734     {&hf_docsis_dcd_rule_tunl_addr,
735       {
736       "DSG Rule Tunnel MAC Address", 
737       "docsis_dcd.rule_tunl_addr",
738       FT_ETHER, BASE_NONE, NULL, 0x0,
739       NULL, 
740       HFILL
741       }
742     },
743     {&hf_docsis_dcd_rule_cfr_id,
744       {
745       "DSG Rule Classifier ID", 
746       "docsis_dcd.rule_cfr_id",
747       FT_UINT16, BASE_DEC, NULL, 0x0,
748       NULL, 
749       HFILL
750       }
751     },
752     {&hf_docsis_dcd_rule_vendor_spec,
753       {
754       "DSG Rule Vendor Specific Parameters", 
755       "docsis_dcd.rule_vendor_spec",
756       FT_BYTES, BASE_NONE, NULL, 0x0,
757       NULL, 
758       HFILL
759       }
760     },
761     {&hf_docsis_dcd_cfg_chan,
762       {
763       "DSG Configuration Channel", 
764       "docsis_dcd.cfg_chan",
765       FT_UINT32, BASE_DEC, NULL, 0x0,
766       NULL, 
767       HFILL
768       }
769     },
770     {&hf_docsis_dcd_cfg_tdsg1,
771       {
772       "DSG Initialization Timeout (Tdsg1)", 
773       "docsis_dcd.cfg_tdsg1",
774       FT_UINT16, BASE_DEC, NULL, 0x0,
775       NULL, 
776       HFILL
777       }
778     },
779     {&hf_docsis_dcd_cfg_tdsg2,
780       {
781       "DSG Operational Timeout (Tdsg2)", 
782       "docsis_dcd.cfg_tdsg2",
783       FT_UINT16, BASE_DEC, NULL, 0x0,
784       NULL, 
785       HFILL
786       }
787     },
788     {&hf_docsis_dcd_cfg_tdsg3,
789       {
790       "DSG Two-Way Retry Timer (Tdsg3)", 
791       "docsis_dcd.cfg_tdsg3",
792       FT_UINT16, BASE_DEC, NULL, 0x0,
793       NULL, 
794       HFILL
795       }
796     },
797     {&hf_docsis_dcd_cfg_tdsg4,
798       {
799       "DSG One-Way Retry Timer (Tdsg4)", 
800       "docsis_dcd.cfg_tdsg4",
801       FT_UINT16, BASE_DEC, NULL, 0x0,
802       NULL, 
803       HFILL
804       }
805     },
806     {&hf_docsis_dcd_cfg_vendor_spec,
807       {
808       "DSG Configuration Vendor Specific Parameters", 
809       "docsis_dcd.cfg_vendor_spec",
810       FT_BYTES, BASE_NONE, NULL, 0x0,
811       NULL, 
812       HFILL
813       }
814     },
815
816   };
817
818 /* Setup protocol subtree array */
819   static gint *ett[] = {
820     &ett_docsis_dcd,
821     &ett_docsis_dcd_cfr,
822     &ett_docsis_dcd_cfr_ip,
823     &ett_docsis_dcd_rule,
824     &ett_docsis_dcd_clid,
825     &ett_docsis_dcd_cfg,
826   };
827
828 /* Register the protocol name and description */
829   proto_docsis_dcd =
830     proto_register_protocol ("DOCSIS Downstream Channel Descriptor",
831                              "DOCSIS DCD", "docsis_dcd");
832
833 /* Required function calls to register the header fields and subtrees used */
834   proto_register_field_array (proto_docsis_dcd, hf, array_length (hf));
835   proto_register_subtree_array (ett, array_length (ett));
836
837   register_dissector ("docsis_dcd", dissect_dcd, proto_docsis_dcd);
838 }
839
840
841 /* If this dissector uses sub-dissector registration add a registration routine.
842    This format is required because a script is used to find these routines and
843    create the code that calls these routines.
844 */
845 void
846 proto_reg_handoff_docsis_dcd (void)
847 {
848   dissector_handle_t docsis_dcd_handle;
849
850   docsis_dcd_handle = find_dissector ("docsis_dcd");
851   dissector_add_uint ("docsis_mgmt", 0x20, docsis_dcd_handle);
852
853 }