Use tvb_memeql() and tvb_memcpy().
[metze/wireshark/wip.git] / epan / dissectors / packet-cops.c
1 /* packet-cops.c
2  * Routines for the COPS (Common Open Policy Service) protocol dissection
3  *
4  * RFC 2748 The COPS (Common Open Policy Service) Protocol
5  * RFC 3084 COPS Usage for Policy Provisioning (COPS-PR)
6  * RFC 3159 Structure of Policy Provisioning Information (SPPI)
7  *
8  * Copyright 2000, Heikki Vatiainen <hessu@cs.tut.fi>
9  *
10  * Added PacketCable D-QoS specifications by Dick Gooris <gooris@lucent.com>
11  *
12  * Taken from PacketCable specifications :
13  *    PacketCable Dynamic Quality-of-Service Specification
14  *    Based on PKT-SP-DQOS-I09-040402 (April 2, 2004)
15  *
16  *    PacketCable Multimedia Specification
17  *    Based on PKT-SP-MM-I04-080522 and PKT-SP-MM-I05-091029
18  *
19  *    www.packetcable.com
20  *
21  * Implemented in wireshark at April 7-8, 2004
22  *
23  * $Id$
24  *
25  * Wireshark - Network traffic analyzer
26  * By Gerald Combs <gerald@wireshark.org>
27  * Copyright 1998 Gerald Combs
28  *
29  * This program is free software; you can redistribute it and/or
30  * modify it under the terms of the GNU General Public License
31  * as published by the Free Software Foundation; either version 2
32  * of the License, or (at your option) any later version.
33  *
34  * This program is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37  * GNU General Public License for more details.
38  *
39  * You should have received a copy of the GNU General Public License
40  * along with this program; if not, write to the Free Software
41  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
42  */
43
44 /*
45  * Some of the development of the COPS protocol decoder was sponsored by
46  * Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary
47  * CableLabs' specifications. Your license and use of this protocol decoder
48  * does not mean that you are licensed to use the CableLabs'
49  * specifications.  If you have questions about this protocol, contact
50  * jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional
51  * information.
52  */
53
54
55 #ifdef HAVE_CONFIG_H
56 # include "config.h"
57 #endif
58
59 #include <stdlib.h>
60 #include <string.h>
61 #include <ctype.h>
62
63 #include <glib.h>
64
65 #include "isprint.h"
66
67 #include <epan/packet.h>
68 #include <epan/emem.h>
69 #include "packet-ipv6.h"
70 #include "packet-tcp.h"
71
72 #include <epan/oids.h>
73 #include <epan/prefs.h>
74 #include <epan/expert.h>
75 #include <epan/asn1.h>
76 #include "packet-ber.h"
77
78 /* XXX - The "plain" COPS port (3288) can be overridden in the prefs.
79    The PacketCable port cannot - should this be the case? */
80 #define TCP_PORT_COPS 3288
81 #define TCP_PORT_PKTCABLE_COPS 2126
82 #define TCP_PORT_PKTCABLE_MM_COPS 3918
83
84 /* Preference: Variable to hold the tcp port preference */
85 static guint global_cops_tcp_port = TCP_PORT_COPS;
86
87 /* Preference: desegmentation of COPS */
88 static gboolean cops_desegment = TRUE;
89
90 #define COPS_OBJECT_HDR_SIZE 4
91
92 /* Null string of type "guchar[]". */
93 static const guchar nullstring[] = "";
94
95 #define SAFE_STRING(s)  (((s) != NULL) ? (s) : nullstring)
96
97 static const value_string cops_flags_vals[] = {
98   { 0x00,          "None" },
99   { 0x01,          "Solicited Message Flag Bit" },
100   { 0, NULL },
101 };
102
103 /* The different COPS message types */
104 enum cops_op_code {
105   COPS_NO_MSG,          /* Not a COPS Message type     */
106
107   COPS_MSG_REQ,         /* Request (REQ)               */
108   COPS_MSG_DEC,         /* Decision (DEC)              */
109   COPS_MSG_RPT,         /* Report State (RPT)          */
110   COPS_MSG_DRQ,         /* Delete Request State (DRQ)  */
111   COPS_MSG_SSQ,         /* Synchronize State Req (SSQ) */
112   COPS_MSG_OPN,         /* Client-Open (OPN)           */
113   COPS_MSG_CAT,         /* Client-Accept (CAT)         */
114   COPS_MSG_CC,          /* Client-Close (CC)           */
115   COPS_MSG_KA,          /* Keep-Alive (KA)             */
116   COPS_MSG_SSC,         /* Synchronize Complete (SSC)  */
117
118   COPS_LAST_OP_CODE     /* For error checking          */
119 };
120
121 static const value_string cops_op_code_vals[] = {
122   { COPS_MSG_REQ,          "Request (REQ)" },
123   { COPS_MSG_DEC,          "Decision (DEC)" },
124   { COPS_MSG_RPT,          "Report State (RPT)" },
125   { COPS_MSG_DRQ,          "Delete Request State (DRQ)" },
126   { COPS_MSG_SSQ,          "Synchronize State Req (SSQ)" },
127   { COPS_MSG_OPN,          "Client-Open (OPN)" },
128   { COPS_MSG_CAT,          "Client-Accept (CAT)" },
129   { COPS_MSG_CC,           "Client-Close (CC)" },
130   { COPS_MSG_KA,           "Keep-Alive (KA)" },
131   { COPS_MSG_SSC,          "Synchronize Complete (SSC)" },
132   { 0, NULL },
133 };
134
135
136 /* The different objects in COPS messages */
137 enum cops_c_num {
138   COPS_NO_OBJECT,        /* Not a COPS Object type               */
139
140   COPS_OBJ_HANDLE,       /* Handle Object (Handle)               */
141   COPS_OBJ_CONTEXT,      /* Context Object (Context)             */
142   COPS_OBJ_IN_INT,       /* In-Interface Object (IN-Int)         */
143   COPS_OBJ_OUT_INT,      /* Out-Interface Object (OUT-Int)       */
144   COPS_OBJ_REASON,       /* Reason Object (Reason)               */
145   COPS_OBJ_DECISION,     /* Decision Object (Decision)           */
146   COPS_OBJ_LPDPDECISION, /* LPDP Decision Object (LPDPDecision)  */
147   COPS_OBJ_ERROR,        /* Error Object (Error)                 */
148   COPS_OBJ_CLIENTSI,     /* Client Specific Information Object (ClientSI) */
149   COPS_OBJ_KATIMER,      /* Keep-Alive Timer Object (KATimer)    */
150   COPS_OBJ_PEPID,        /* PEP Identification Object (PEPID)    */
151   COPS_OBJ_REPORT_TYPE,  /* Report-Type Object (Report-Type)     */
152   COPS_OBJ_PDPREDIRADDR, /* PDP Redirect Address Object (PDPRedirAddr) */
153   COPS_OBJ_LASTPDPADDR,  /* Last PDP Address (LastPDPaddr)       */
154   COPS_OBJ_ACCTTIMER,    /* Accounting Timer Object (AcctTimer)  */
155   COPS_OBJ_INTEGRITY,    /* Message Integrity Object (Integrity) */
156   COPS_LAST_C_NUM        /* For error checking                   */
157 };
158
159 static const value_string cops_c_num_vals[] = {
160   { COPS_OBJ_HANDLE,       "Handle Object (Handle)" },
161   { COPS_OBJ_CONTEXT,      "Context Object (Context)" },
162   { COPS_OBJ_IN_INT,       "In-Interface Object (IN-Int)" },
163   { COPS_OBJ_OUT_INT,      "Out-Interface Object (OUT-Int)" },
164   { COPS_OBJ_REASON,       "Reason Object (Reason)" },
165   { COPS_OBJ_DECISION,     "Decision Object (Decision)" },
166   { COPS_OBJ_LPDPDECISION, "LPDP Decision Object (LPDPDecision)" },
167   { COPS_OBJ_ERROR,        "Error Object (Error)" },
168   { COPS_OBJ_CLIENTSI,     "Client Specific Information Object (ClientSI)" },
169   { COPS_OBJ_KATIMER,      "Keep-Alive Timer Object (KATimer)" },
170   { COPS_OBJ_PEPID,        "PEP Identification Object (PEPID)" },
171   { COPS_OBJ_REPORT_TYPE,  "Report-Type Object (Report-Type)" },
172   { COPS_OBJ_PDPREDIRADDR, "PDP Redirect Address Object (PDPRedirAddr)" },
173   { COPS_OBJ_LASTPDPADDR,  "Last PDP Address (LastPDPaddr)" },
174   { COPS_OBJ_ACCTTIMER,    "Accounting Timer Object (AcctTimer)" },
175   { COPS_OBJ_INTEGRITY,    "Message Integrity Object (Integrity)" },
176   { 0, NULL },
177 };
178
179
180 /* The different objects in COPS-PR messages */
181 enum cops_s_num {
182   COPS_NO_PR_OBJECT,     /* Not a COPS-PR Object type               */
183   COPS_OBJ_PRID,         /* Provisioning Instance Identifier (PRID) */
184   COPS_OBJ_PPRID,        /* Prefix Provisioning Instance Identifier (PPRID) */
185   COPS_OBJ_EPD,          /* Encoded Provisioning Instance Data (EPD) */
186   COPS_OBJ_GPERR,        /* Global Provisioning Error Object (GPERR) */
187   COPS_OBJ_CPERR,        /* PRC Class Provisioning Error Object (CPERR) */
188   COPS_OBJ_ERRPRID,      /* Error Provisioning Instance Identifier (ErrorPRID)*/
189
190   COPS_LAST_S_NUM        /* For error checking                   */
191 };
192
193
194 static const value_string cops_s_num_vals[] = {
195   { COPS_OBJ_PRID,         "Provisioning Instance Identifier (PRID)" },
196   { COPS_OBJ_PPRID,        "Prefix Provisioning Instance Identifier (PPRID)" },
197   { COPS_OBJ_EPD,          "Encoded Provisioning Instance Data (EPD)" },
198   { COPS_OBJ_GPERR,        "Global Provisioning Error Object (GPERR)" },
199   { COPS_OBJ_CPERR,        "PRC Class Provisioning Error Object (CPERR)" },
200   { COPS_OBJ_ERRPRID,      "Error Provisioning Instance Identifier (ErrorPRID)" },
201   { 0, NULL },
202
203 };
204
205 /* R-Type is carried within the Context Object */
206 static const value_string cops_r_type_vals[] = {
207   { 0x01, "Incoming-Message/Admission Control request" },
208   { 0x02, "Resource-Allocation request" },
209   { 0x04, "Outgoing-Message request" },
210   { 0x08, "Configuration request" },
211   { 0, NULL },
212 };
213 /* S-Type is carried within the ClientSI Object for COPS-PR*/
214 static const value_string cops_s_type_vals[] = {
215   { 0x01, "BER" },
216   { 0, NULL },
217 };
218
219 /* Reason-Code is carried within the Reason object */
220 static const value_string cops_reason_vals[] = {
221   { 1,  "Unspecified" },
222   { 2,  "Management" },
223   { 3,  "Preempted (Another request state takes precedence)" },
224   { 4,  "Tear (Used to communicate a signaled state removal)" },
225   { 5,  "Timeout (Local state has timed-out)" },
226   { 6,  "Route Change (Change invalidates request state)" },
227   { 7,  "Insufficient Resources (No local resource available)" },
228   { 8,  "PDP's Directive (PDP decision caused the delete)" },
229   { 9,  "Unsupported decision (PDP decision not supported)" },
230   { 10, "Synchronize Handle Unknown" },
231   { 11, "Transient Handle (stateless event)" },
232   { 12, "Malformed Decision (could not recover)" },
233   { 13, "Unknown COPS Object from PDP" },
234   { 0, NULL },
235 };
236
237 /* Command-Code is carried within the Decision object if C-Type is 1 */
238 static const value_string cops_dec_cmd_code_vals[] = {
239   { 0, "NULL Decision (No configuration data available)" },
240   { 1, "Install (Admit request/Install configuration)" },
241   { 2, "Remove (Remove request/Remove configuration)" },
242   { 0, NULL },
243 };
244
245 /* Decision flags are also carried with the Decision object if C-Type is 1 */
246 static const value_string cops_dec_cmd_flag_vals[] = {
247   { 0x00, "<None set>" },
248   { 0x01, "Trigger Error (Trigger error message if set)" },
249   { 0, NULL },
250 };
251
252 /* Error-Code from Error object */
253 static const value_string cops_error_vals[] = {
254   {1,  "Bad handle" },
255   {2,  "Invalid handle reference" },
256   {3,  "Bad message format (Malformed Message)" },
257   {4,  "Unable to process (server gives up on query)" },
258   {5,  "Mandatory client-specific info missing" },
259   {6,  "Unsupported client" },
260   {7,  "Mandatory COPS object missing" },
261   {8,  "Client Failure" },
262   {9,  "Communication Failure" },
263   {10, "Unspecified" },
264   {11, "Shutting down" },
265   {12, "Redirect to Preferred Server" },
266   {13, "Unknown COPS Object" },
267   {14, "Authentication Failure" },
268   {15, "Authentication Required" },
269   {0,  NULL },
270 };
271 /* Error-Code from GPERR object */
272 static const value_string cops_gperror_vals[] = {
273   {1,  "AvailMemLow" },
274   {2,  "AvailMemExhausted" },
275   {3,  "unknownASN.1Tag" },
276   {4,  "maxMsgSizeExceeded" },
277   {5,  "unknownError" },
278   {6,  "maxRequestStatesOpen" },
279   {7,  "invalidASN.1Length" },
280   {8,  "invalidObjectPad" },
281   {9,  "unknownPIBData" },
282   {10, "unknownCOPSPRObject" },
283   {11, "malformedDecision" },
284   {0,  NULL },
285 };
286
287 /* Error-Code from CPERR object */
288 static const value_string cops_cperror_vals[] = {
289   {1,  "priSpaceExhausted" },
290   {2,  "priInstanceInvalid" },
291   {3,  "attrValueInvalid" },
292   {4,  "attrValueSupLimited" },
293   {5,  "attrEnumSupLimited" },
294   {6,  "attrMaxLengthExceeded" },
295   {7,  "attrReferenceUnknown" },
296   {8,  "priNotifyOnly" },
297   {9,  "unknownPrc" },
298   {10, "tooFewAttrs" },
299   {11, "invalidAttrType" },
300   {12, "deletedInRef" },
301   {13, "priSpecificError" },
302   {0,  NULL },
303 };
304
305
306 /* Report-Type from Report-Type object */
307 static const value_string cops_report_type_vals[] = {
308   {1, " Success   : Decision was successful at the PEP" },
309   {2, " Failure   : Decision could not be completed by PEP" },
310   {3, " Accounting: Accounting update for an installed state" },
311   {0, NULL },
312 };
313
314
315 /* Client-type descriptions */
316 /* http://www.iana.org/assignments/cops-parameters */
317
318 /* PacketCable Types */
319
320 /* static dissector_handle_t sdp_handle; */
321
322 #define COPS_CLIENT_PC_DQOS     0x8008
323 #define COPS_CLIENT_PC_MM       0x800a
324
325 static const value_string cops_client_type_vals[] = {
326         {0,                   "None"},
327         {1,                   "RSVP"},
328         {2,                   "DiffServ QoS"},
329         {0x8001,              "IP Highway"},
330         {0x8002,              "IP Highway"},
331         {0x8003,              "IP Highway"},
332         {0x8004,              "IP Highway"},
333         {0x8005,              "Fujitsu"},
334         {0x8006,              "HP OpenView PolicyXpert"},
335         {0x8007,              "HP OpenView PolicyXpert"},
336         {COPS_CLIENT_PC_DQOS, "PacketCable Dynamic Quality-of-Service"},
337         {0x8009,              "3GPP"},
338         {COPS_CLIENT_PC_MM,   "PacketCable Multimedia"},
339         {0, NULL},
340 };
341
342 /* The next tables are for PacketCable */
343
344 /* Transaction ID table */
345 static const value_string table_cops_dqos_transaction_id[] =
346 {
347   { 0x1,  "Gate Alloc" },
348   { 0x2,  "Gate Alloc Ack" },
349   { 0x3,  "Gate Alloc Err" },
350   { 0x4,  "Gate Set" },
351   { 0x5,  "Gate Set Ack" },
352   { 0x6,  "Gate Set Err" },
353   { 0x7,  "Gate Info" },
354   { 0x8,  "Gate Info Ack" },
355   { 0x9,  "Gate Info Err" },
356   { 0xa,  "Gate Delete" },
357   { 0xb,  "Gate Delete Ack" },
358   { 0xc,  "Gate Delete Err" },
359   { 0xd,  "Gate Open" },
360   { 0xe,  "Gate Close" },
361   { 0, NULL },
362 };
363
364 /* Direction */
365 static const value_string table_cops_direction[] =
366 {
367   { 0x0,  "Downstream gate" },
368   { 0x1,  "Upstream gate" },
369   { 0, NULL },
370 };
371
372 /* Session Class */
373 static const value_string table_cops_session_class[] =
374 {
375   { 0x0,  "Unspecified" },
376   { 0x1,  "Normal priority VoIP session" },
377   { 0x2,  "High priority VoIP session" },
378   { 0x3,  "Reserved" },
379   { 0, NULL },
380 };
381
382 /* Reason Code */
383 static const value_string table_cops_reason_code[] =
384 {
385   { 0x0,  "Gate Delete Operation" },
386   { 0x1,  "Gate Close Operation" },
387   { 0, NULL },
388 };
389
390 /* Reason Sub Code - Delete */
391 static const value_string table_cops_reason_subcode_delete[] =
392 {
393   { 0x0,  "Normal Operation" },
394   { 0x1,  "Local Gate-coordination not completed" },
395   { 0x2,  "Remote Gate-coordination not completed" },
396   { 0x3,  "Authorization revoked" },
397   { 0x4,  "Unexpected Gate-Open" },
398   { 0x5,  "Local Gate-Close failure" },
399   { 0x127,"Unspecified error" },
400   { 0, NULL },
401 };
402
403 /* Reason Sub Code - Close */
404 static const value_string table_cops_reason_subcode_close[] =
405 {
406   { 0x0,  "Client initiated release (normal operation)" },
407   { 0x1,  "Reservation reassignment (e.g., for priority session)" },
408   { 0x2,  "Lack of reservation maintenance (e.g., RSVP refreshes)" },
409   { 0x3,  "Lack of Docsis Mac-layer responses (e.g., station maintenance)" },
410   { 0x4,  "Timer T0 expiration; no Gate-Set received from CMS" },
411   { 0x5,  "Timer T1 expiration; no Commit received from MTA" },
412   { 0x6,  "Timer T7 expiration; Service Flow reservation timeout" },
413   { 0x7,  "Timer T8 expiration; Service Flow inactivity in the upstream direction" },
414   { 0x127,"Unspecified error" },
415   { 0, NULL },
416 };
417
418 /* PacketCable Error */
419 static const value_string table_cops_packetcable_error[] =
420 {
421   { 0x1,  "No gates urrently available" },
422   { 0x2,  "Unknown Gate ID" },
423   { 0x3,  "Illegal Session Class value" },
424   { 0x4,  "Subscriber exceeded gate limit" },
425   { 0x5,  "Gate already set" },
426   { 0x6,  "Missing Required Object" },
427   { 0x7,  "Invalid Object" },
428   { 0x127,"Unspecified error" },
429   { 0, NULL },
430 };
431
432
433 /* PacketCable Multimedia */
434
435 static const value_string table_cops_mm_transaction_id[] = {
436         {1,  "Reserved"},
437         {2,  "Reserved"},
438         {3,  "Reserved"},
439         {4,  "Gate Set"},
440         {5,  "Gate Set Ack"},
441         {6,  "Gate Set Err"},
442         {7,  "Gate Info"},
443         {8,  "Gate Info Ack"},
444         {9,  "Gate Info Err"},
445         {10, "Gate Delete"},
446         {11, "Gate Delete Ack"},
447         {12, "Gate Delete Err"},
448         {13, "Gate Open"},
449         {14, "Gate Close"},
450         {15, "Gate Report State"},
451         {16, "Invalid Gate Cmd Err"},
452         {17, "PDP Config"},
453         {18, "PDP Config Ack"},
454         {19, "PDP Config Error"},
455         {20, "Synch Request"},
456         {21, "Synch Report"},
457         {22, "Synch Complete"},
458         {23, "Message Receipt"},
459         {0, NULL },
460 };
461
462 static const value_string pcmm_activation_state_vals[] = {
463         {0, "Inactive"},
464         {1, "Active"},
465         {0, NULL },
466 };
467
468 static const value_string pcmm_action_vals[] = {
469         {0, "Add classifier"},
470         {1, "Replace classifier"},
471         {2, "Delete classifier"},
472         {3, "No change"},
473         {0, NULL },
474 };
475
476 static const value_string pcmm_flow_spec_service_vals[] = {
477         {2, "Guaranteed Rate"},
478         {5, "Controlled Load"},
479         {0, NULL },
480 };
481
482 static const value_string pcmm_report_type_vals[] = {
483         {0, "Standard Report Data"},
484         {1, "Complete Gate Data"},
485         {0, NULL},
486 };
487
488 static const value_string pcmm_synch_type_vals[] = {
489         {0, "Full Synchronization"},
490         {1, "Incremental Synchronization"},
491         {0, NULL},
492 };
493
494 static const value_string pcmm_packetcable_error_code[] = {
495         {1,  "Insufficient Resources"},
496         {2,  "Unknown GateID"},
497         {6,  "Missing Required Object"},
498         {7,  "Invalid Object"},
499         {8,  "Volume-Based Usage Limit Exceeded"},
500         {9,  "Time-Based Usage Limit Exceeded"},
501         {10, "Session Class Limit Exceeded"},
502         {11, "Undefined Service Class Name"},
503         {12, "Incompatible Envelope"},
504         {13, "Invalid SubscriberID"},
505         {14, "Unauthorized AMID"},
506         {15, "Number of Classifiers Not Supported"},
507         {16, "Policy Exception"},
508         {17, "Invalid Field Value in Object"},
509         {18, "Transport Error"},
510         {19, "Unknown Gate Command"},
511         {20, "Unauthorized PSID"},
512         {21, "No State for PDP"},
513         {22, "Unsupported Synch Type"},
514         {23, "Incremental Data Incomplete"},
515         {127, "Other, Unspecified Error"},
516         {0, NULL},
517 };
518
519 static const value_string pcmm_gate_state[] = {
520         {1, "Idle/Closed"},
521         {2, "Authorized"},
522         {3, "Reserved"},
523         {4, "Committed"},
524         {5, "Committed-Recovery"},
525         {0, NULL},
526 };
527
528 static const value_string pcmm_gate_state_reason[] = {
529         {1,  "Close initiated by CMTS due to reservation reassignment"},
530         {2,  "Close initiated by CMTS due to lack of DOCSIS MAC-layer responses"},
531         {3,  "Close initiated by CMTS due to timer T1 expiration"},
532         {4,  "Close initiated by CMTS due to timer T2 expiration"},
533         {5,  "Inactivity timer expired due to Service Flow inactivity (timer T3 expiration)"},
534         {6,  "Close initiated by CMTS due to lack of Reservation Maintenance"},
535         {7,  "Gate state unchanged, but volume limit reached"},
536         {8,  "Close initiated by CMTS due to timer T4 expiration"},
537         {9,  "Gate state unchanged, but timer T2 expiration caused reservation reduction"},
538         {10, "Gate state unchanged, but time limit reached"},
539         {11, "Close initiated by Policy Server or CMTS, volume limit reached"},
540         {12, "Close initiated by Policy Server or CMTS, time limit reached"},
541         {13, "Close initiated by CMTS, other"},
542         {65535, "Other"},
543         {0, NULL},
544 };
545
546
547 /* End of PacketCable Tables */
548
549
550 /* Initialize the protocol and registered fields */
551 static gint proto_cops = -1;
552 static gint hf_cops_ver_flags = -1;
553 static gint hf_cops_version = -1;
554 static gint hf_cops_flags = -1;
555
556 static gint hf_cops_op_code = -1;
557 static gint hf_cops_client_type = -1;
558 static gint hf_cops_msg_len = -1;
559
560 static gint hf_cops_obj_len = -1;
561 static gint hf_cops_obj_c_num = -1;
562 static gint hf_cops_obj_c_type = -1;
563
564 static gint hf_cops_obj_s_num = -1;
565 static gint hf_cops_obj_s_type = -1;
566
567 static gint hf_cops_r_type_flags = -1;
568 static gint hf_cops_m_type_flags = -1;
569
570 static gint hf_cops_in_int_ipv4 = -1;
571 static gint hf_cops_in_int_ipv6 = -1;
572 static gint hf_cops_out_int_ipv4 = -1;
573 static gint hf_cops_out_int_ipv6 = -1;
574 static gint hf_cops_int_ifindex = -1;
575
576 static gint hf_cops_reason = -1;
577 static gint hf_cops_reason_sub = -1;
578
579 static gint hf_cops_dec_cmd_code = -1;
580 static gint hf_cops_dec_flags = -1;
581
582 static gint hf_cops_error = -1;
583 static gint hf_cops_error_sub = -1;
584
585 static gint hf_cops_gperror = -1;
586 static gint hf_cops_gperror_sub = -1;
587
588 static gint hf_cops_cperror = -1;
589 static gint hf_cops_cperror_sub = -1;
590
591 static gint hf_cops_katimer = -1;
592
593 static gint hf_cops_pepid = -1;
594
595 static gint hf_cops_report_type = -1;
596
597 static gint hf_cops_pdprediraddr_ipv4 = -1;
598 static gint hf_cops_pdprediraddr_ipv6 = -1;
599 static gint hf_cops_lastpdpaddr_ipv4 = -1;
600 static gint hf_cops_lastpdpaddr_ipv6 = -1;
601 static gint hf_cops_pdp_tcp_port = -1;
602
603 static gint hf_cops_accttimer = -1;
604
605 static gint hf_cops_key_id = -1;
606 static gint hf_cops_seq_num = -1;
607
608 static gint hf_cops_prid_oid = -1;
609 static gint hf_cops_pprid_oid = -1;
610 static gint hf_cops_errprid_oid = -1;
611 static gint hf_cops_epd_null = -1;
612 static gint hf_cops_epd_int = -1;
613 static gint hf_cops_epd_octets = -1;
614 static gint hf_cops_epd_oid = -1;
615 static gint hf_cops_epd_ipv4 = -1;
616 static gint hf_cops_epd_u32 = -1;
617 static gint hf_cops_epd_ticks = -1;
618 static gint hf_cops_epd_opaque = -1;
619 static gint hf_cops_epd_i64 = -1;
620 static gint hf_cops_epd_u64 = -1;
621 static gint hf_cops_epd_unknown = -1;
622
623 /* For PacketCable D-QoS */
624 static gint hf_cops_subtree = -1;
625 static gint hf_cops_pc_activity_count = -1;
626 static gint hf_cops_pc_algorithm = -1;
627 static gint hf_cops_pc_close_subcode = -1;
628 static gint hf_cops_pc_cmts_ip = -1;
629 static gint hf_cops_pc_cmts_ip_port = -1;
630 static gint hf_cops_pc_prks_ip = -1;
631 static gint hf_cops_pc_prks_ip_port = -1;
632 static gint hf_cops_pc_srks_ip = -1;
633 static gint hf_cops_pc_srks_ip_port = -1;
634 static gint hf_cops_pc_delete_subcode = -1;
635 static gint hf_cops_pc_dest_ip = -1;
636 static gint hf_cops_pc_dest_port = -1;
637 static gint hf_cops_pc_direction = -1;
638 static gint hf_cops_pc_ds_field = -1;
639 static gint hf_cops_pc_gate_id = -1;
640 static gint hf_cops_pc_gate_spec_flags = -1;
641 static gint hf_cops_pc_gate_command_type = -1;
642 static gint hf_cops_pc_key = -1;
643 static gint hf_cops_pc_max_packet_size = -1;
644 static gint hf_cops_pc_min_policed_unit = -1;
645 static gint hf_cops_pc_packetcable_err_code = -1;
646 static gint hf_cops_pc_packetcable_sub_code = -1;
647 static gint hf_cops_pc_peak_data_rate = -1;
648 static gint hf_cops_pc_protocol_id = -1;
649 static gint hf_cops_pc_reason_code = -1;
650 static gint hf_cops_pc_remote_flags = -1;
651 static gint hf_cops_pc_remote_gate_id = -1;
652 static gint hf_cops_pc_reserved = -1;
653 static gint hf_cops_pc_session_class = -1;
654 static gint hf_cops_pc_slack_term = -1;
655 static gint hf_cops_pc_spec_rate = -1;
656 static gint hf_cops_pc_src_ip = -1;
657 static gint hf_cops_pc_src_port = -1;
658 static gint hf_cops_pc_subscriber_id_ipv4 = -1;
659 static gint hf_cops_pc_subscriber_id_ipv6 = -1;
660 static gint hf_cops_pc_t1_value = -1;
661 static gint hf_cops_pc_t7_value = -1;
662 static gint hf_cops_pc_t8_value = -1;
663 static gint hf_cops_pc_token_bucket_rate = -1;
664 static gint hf_cops_pc_token_bucket_size = -1;
665 static gint hf_cops_pc_transaction_id = -1;
666 static gint hf_cops_pc_bcid_ts = -1;
667 static gint hf_cops_pc_bcid = -1;
668 static gint hf_cops_pc_bcid_ev = -1;
669 static gint hf_cops_pc_dfcdc_ip = -1;
670 static gint hf_cops_pc_dfccc_ip = -1;
671 static gint hf_cops_pc_dfcdc_ip_port = -1;
672 static gint hf_cops_pc_dfccc_ip_port = -1;
673 static gint hf_cops_pc_dfccc_id = -1;
674
675 /* PacketCable Multimedia */
676 static gint hf_cops_pcmm_amid_app_type = -1;
677 static gint hf_cops_pcmm_amid_am_tag = -1;
678 static gint hf_cops_pcmm_gate_spec_flags = -1;
679 static gint hf_cops_pcmm_gate_spec_dscp_tos_field = -1;
680 static gint hf_cops_pcmm_gate_spec_dscp_tos_mask = -1;
681 static gint hf_cops_pcmm_gate_spec_session_class_id = -1;
682 static gint hf_cops_pcmm_gate_spec_session_class_id_priority = -1;
683 static gint hf_cops_pcmm_gate_spec_session_class_id_preemption = -1;
684 static gint hf_cops_pcmm_gate_spec_session_class_id_configurable = -1;
685 static gint hf_cops_pcmm_gate_spec_timer_t1 = -1;
686 static gint hf_cops_pcmm_gate_spec_timer_t2 = -1;
687 static gint hf_cops_pcmm_gate_spec_timer_t3 = -1;
688 static gint hf_cops_pcmm_gate_spec_timer_t4 = -1;
689 static gint hf_cops_pcmm_classifier_protocol_id = -1;
690 static gint hf_cops_pcmm_classifier_dscp_tos_field = -1;
691 static gint hf_cops_pcmm_classifier_dscp_tos_mask = -1;
692 static gint hf_cops_pcmm_classifier_src_addr = -1;
693 static gint hf_cops_pcmm_classifier_src_mask = -1;
694 static gint hf_cops_pcmm_classifier_dst_addr = -1;
695 static gint hf_cops_pcmm_classifier_dst_mask = -1;
696 static gint hf_cops_pcmm_classifier_src_port = -1;
697 static gint hf_cops_pcmm_classifier_src_port_end = -1;
698 static gint hf_cops_pcmm_classifier_dst_port = -1;
699 static gint hf_cops_pcmm_classifier_dst_port_end = -1;
700 static gint hf_cops_pcmm_classifier_priority = -1;
701 static gint hf_cops_pcmm_classifier_classifier_id = -1;
702 static gint hf_cops_pcmm_classifier_activation_state = -1;
703 static gint hf_cops_pcmm_classifier_action = -1;
704 static gint hf_cops_pcmm_classifier_flags = -1;
705 static gint hf_cops_pcmm_classifier_tc_low = -1;
706 static gint hf_cops_pcmm_classifier_tc_high = -1;
707 static gint hf_cops_pcmm_classifier_tc_mask = -1;
708 static gint hf_cops_pcmm_classifier_flow_label = -1;
709 static gint hf_cops_pcmm_classifier_next_header_type = -1;
710 static gint hf_cops_pcmm_classifier_source_prefix_length = -1;
711 static gint hf_cops_pcmm_classifier_destination_prefix_length = -1;
712 static gint hf_cops_pcmm_classifier_src_addr_v6 = -1;
713 static gint hf_cops_pcmm_classifier_dst_addr_v6 = -1;
714 static gint hf_cops_pcmm_flow_spec_envelope = -1;
715 static gint hf_cops_pcmm_flow_spec_service_number = -1;
716 static gint hf_cops_pcmm_docsis_scn = -1;
717 static gint hf_cops_pcmm_envelope = -1;
718 static gint hf_cops_pcmm_traffic_priority = -1;
719 static gint hf_cops_pcmm_request_transmission_policy = -1;
720 static gint hf_cops_pcmm_max_sustained_traffic_rate = -1;
721 static gint hf_cops_pcmm_max_traffic_burst = -1;
722 static gint hf_cops_pcmm_min_reserved_traffic_rate = -1;
723 static gint hf_cops_pcmm_ass_min_rtr_packet_size = -1;
724 static gint hf_cops_pcmm_max_concat_burst = -1;
725 static gint hf_cops_pcmm_req_att_mask = -1;
726 static gint hf_cops_pcmm_forbid_att_mask = -1;
727 static gint hf_cops_pcmm_att_aggr_rule_mask = -1;
728 static gint hf_cops_pcmm_nominal_polling_interval = -1;
729 static gint hf_cops_pcmm_tolerated_poll_jitter = -1;
730 static gint hf_cops_pcmm_unsolicited_grant_size = -1;
731 static gint hf_cops_pcmm_grants_per_interval = -1;
732 static gint hf_cops_pcmm_nominal_grant_interval = -1;
733 static gint hf_cops_pcmm_tolerated_grant_jitter = -1;
734 static gint hf_cops_pcmm_down_resequencing = -1;
735 static gint hf_cops_pcmm_down_peak_traffic_rate = -1;
736 static gint hf_cops_pcmm_max_downstream_latency = -1;
737 static gint hf_cops_pcmm_volume_based_usage_limit = -1;
738 static gint hf_cops_pcmm_time_based_usage_limit = -1;
739 static gint hf_cops_pcmm_gate_time_info = -1;
740 static gint hf_cops_pcmm_gate_usage_info = -1;
741 static gint hf_cops_pcmm_packetcable_error_code = -1;
742 static gint hf_cops_pcmm_packetcable_error_subcode = -1;
743 static gint hf_cops_pcmm_packetcable_gate_state = -1;
744 static gint hf_cops_pcmm_packetcable_gate_state_reason = -1;
745 static gint hf_cops_pcmm_packetcable_version_info_major = -1;
746 static gint hf_cops_pcmm_packetcable_version_info_minor = -1;
747 static gint hf_cops_pcmm_psid = -1;
748 static gint hf_cops_pcmm_synch_options_report_type = -1;
749 static gint hf_cops_pcmm_synch_options_synch_type = -1;
750 static gint hf_cops_pcmm_msg_receipt_key = -1;
751 static gint hf_cops_pcmm_userid = -1;
752 static gint hf_cops_pcmm_sharedresourceid = -1;
753
754
755 /* Initialize the subtree pointers */
756 static gint ett_cops = -1;
757 static gint ett_cops_ver_flags = -1;
758 static gint ett_cops_obj = -1;
759 static gint ett_cops_pr_obj = -1;
760 static gint ett_cops_obj_data = -1;
761 static gint ett_cops_r_type_flags = -1;
762 static gint ett_cops_itf = -1;
763 static gint ett_cops_reason = -1;
764 static gint ett_cops_decision = -1;
765 static gint ett_cops_error = -1;
766 static gint ett_cops_clientsi = -1;
767 static gint ett_cops_asn1 = -1;
768 static gint ett_cops_gperror = -1;
769 static gint ett_cops_cperror = -1;
770 static gint ett_cops_pdp = -1;
771
772 /* For PacketCable */
773 static gint ett_cops_subtree = -1;
774
775 static gint ett_docsis_request_transmission_policy = -1;
776
777
778 void proto_reg_handoff_cops(void);
779
780 static guint get_cops_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
781 static void dissect_cops_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
782
783 static int dissect_cops_object(tvbuff_t *tvb, packet_info *pinfo, guint8 op_code, guint32 offset, proto_tree *tree, guint16 client_type);
784 static void dissect_cops_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree,
785                                      guint8 op_code, guint16 client_type, guint8 c_num, guint8 c_type, int len);
786
787 static void dissect_cops_pr_objects(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree, int pr_len,
788                                                                         oid_info_t** oid_info_p, guint32** pprid_subids_p, guint* pprid_subids_len_p);
789 static int dissect_cops_pr_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree,
790                                                                            guint8 s_num, guint8 s_type, int len,
791                                                                            oid_info_t** oid_info_p, guint32** pprid_subids, guint* pprid_subids_len);
792
793 /* Added for PacketCable */
794 static proto_tree *info_to_cops_subtree(tvbuff_t *, proto_tree *, int, int, const char *);
795 static proto_item *info_to_display(tvbuff_t *, proto_item *, int, int, const char *, const value_string *, int, gint *);
796
797 static void cops_transaction_id(tvbuff_t *, packet_info *, proto_tree *, guint8, guint, guint32);
798 static void cops_subscriber_id_v4(tvbuff_t *, proto_tree *, guint, guint32);
799 static void cops_subscriber_id_v6(tvbuff_t *, proto_tree *, guint, guint32);
800 static void cops_gate_id(tvbuff_t *, proto_tree *, guint, guint32);
801 static void cops_activity_count(tvbuff_t *, proto_tree *, guint, guint32);
802 static void cops_gate_specs(tvbuff_t *, proto_tree *, guint, guint32);
803 static void cops_remote_gate_info(tvbuff_t *, proto_tree *, guint, guint32);
804 static void cops_packetcable_reason(tvbuff_t *, proto_tree *, guint, guint32);
805 static void cops_packetcable_error(tvbuff_t *, proto_tree *, guint, guint32);
806 static void cops_event_generation_info(tvbuff_t *, proto_tree *, guint, guint32);
807 static void cops_surveillance_parameters(tvbuff_t *, proto_tree *, guint, guint32);
808
809 static void cops_amid(tvbuff_t *, proto_tree *, guint, guint32);
810
811 static void decode_docsis_request_transmission_policy(tvbuff_t *tvb, guint32 offset, proto_tree *tree, gint hf);
812
813 static void cops_analyze_packetcable_dqos_obj(tvbuff_t *, packet_info *, proto_tree *, guint8, guint32);
814 static void cops_analyze_packetcable_mm_obj(tvbuff_t *, packet_info *, proto_tree *, guint8, guint32);
815
816 static gboolean cops_packetcable = TRUE;
817
818 /* End of addition for PacketCable */
819
820 /* COPS PR Tags */
821
822 #define COPS_IPA    0           /* IP Address */
823 #define COPS_U32    2           /* Unsigned 32*/
824 #define COPS_TIT    3           /* TimeTicks */
825 #define COPS_OPQ    4           /* Opaque */
826 #define COPS_I64    10          /* Integer64 */
827 #define COPS_U64    11          /* Uinteger64 */
828
829 /* COPS PR Types */
830
831 #define COPS_NULL                0
832 #define COPS_INTEGER             1    /* l  */
833 #define COPS_OCTETSTR            2    /* c  */
834 #define COPS_OBJECTID            3    /* ul */
835 #define COPS_IPADDR              4    /* uc */
836 #define COPS_UNSIGNED32          5    /* ul */
837 #define COPS_TIMETICKS           7    /* ul */
838 #define COPS_OPAQUE              8    /* c  */
839 #define COPS_INTEGER64           10   /* ll */
840 #define COPS_UNSIGNED64          11   /* ull  */
841
842 typedef struct _COPS_CNV COPS_CNV;
843
844 struct _COPS_CNV
845 {
846         guint class;
847         guint tag;
848         gint  syntax;
849         const gchar *name;
850         int* hfidp;
851 };
852
853 static COPS_CNV CopsCnv [] =
854 {
855         {BER_CLASS_UNI, BER_UNI_TAG_NULL,                       COPS_NULL,      "NULL" , &hf_cops_epd_null},
856         {BER_CLASS_UNI, BER_UNI_TAG_INTEGER,            COPS_INTEGER,   "INTEGER", &hf_cops_epd_int},
857         {BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING,        COPS_OCTETSTR,  "OCTET STRING", &hf_cops_epd_octets},
858         {BER_CLASS_UNI, BER_UNI_TAG_OID,                        COPS_OBJECTID,  "OBJECTID", &hf_cops_epd_oid},
859         {BER_CLASS_APP, COPS_IPA,                                       COPS_IPADDR,    "IPADDR", &hf_cops_epd_ipv4},
860         {BER_CLASS_APP, COPS_U32,                                       COPS_UNSIGNED32,"UNSIGNED32", &hf_cops_epd_u32},
861         {BER_CLASS_APP, COPS_TIT,                                       COPS_TIMETICKS, "TIMETICKS", &hf_cops_epd_ticks},
862         {BER_CLASS_APP, COPS_OPQ,                                       COPS_OPAQUE,    "OPAQUE", &hf_cops_epd_opaque},
863         {BER_CLASS_APP, COPS_I64,                                       COPS_INTEGER64, "INTEGER64", &hf_cops_epd_i64},
864         {BER_CLASS_APP, COPS_U64,                                       COPS_UNSIGNED64, "UNSIGNED64", &hf_cops_epd_u64},
865         {BER_CLASS_ANY,       0,         -1,                  NULL, NULL}
866 };
867
868 static int cops_tag_cls2syntax ( guint tag, guint cls ) {
869         COPS_CNV *cnv;
870
871
872         cnv = CopsCnv;
873         while (cnv->syntax != -1)
874         {
875                 if (cnv->tag == tag && cnv->class == cls)
876                 {
877                         return *(cnv->hfidp);
878                 }
879                 cnv++;
880         }
881         return hf_cops_epd_unknown;
882 }
883
884
885
886 /* Code to actually dissect the packets */
887 static void
888 dissect_cops(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
889 {
890   tcp_dissect_pdus(tvb, pinfo, tree, cops_desegment, 8,
891                    get_cops_pdu_len, dissect_cops_pdu);
892 }
893
894 static guint
895 get_cops_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
896 {
897   /*
898    * Get the length of the COPS message.
899    */
900   return tvb_get_ntohl(tvb, offset + 4);
901 }
902
903 static void
904 dissect_cops_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
905 {
906   guint8 op_code;
907   guint16 client_type;
908   int object_len;
909
910   col_set_str(pinfo->cinfo, COL_PROTOCOL, "COPS");
911   col_clear(pinfo->cinfo, COL_INFO);
912
913   op_code = tvb_get_guint8(tvb, 1);
914   col_add_fstr(pinfo->cinfo, COL_INFO, "COPS %s",
915                val_to_str(op_code, cops_op_code_vals, "Unknown Op Code"));
916
917   /* Currently used by PacketCable */
918   client_type = tvb_get_ntohs(tvb, 2);
919
920   if (tree) {
921     proto_item *ti, *tv;
922     proto_tree *cops_tree, *ver_flags_tree;
923     guint32 msg_len;
924     guint32 offset = 0;
925     guint8 ver_flags;
926     gint garbage;
927
928     ti = proto_tree_add_item(tree, proto_cops, tvb, offset, -1, FALSE);
929     cops_tree = proto_item_add_subtree(ti, ett_cops);
930
931     /* Version and flags share the same byte, put them in a subtree */
932     ver_flags = tvb_get_guint8(tvb, offset);
933     tv = proto_tree_add_uint_format(cops_tree, hf_cops_ver_flags, tvb, offset, 1,
934                                       ver_flags, "Version: %u, Flags: %s",
935                                       hi_nibble(ver_flags),
936                                       val_to_str(lo_nibble(ver_flags), cops_flags_vals, "Unknown"));
937     ver_flags_tree = proto_item_add_subtree(tv, ett_cops_ver_flags);
938     proto_tree_add_uint(ver_flags_tree, hf_cops_version, tvb, offset, 1, ver_flags);
939     proto_tree_add_uint(ver_flags_tree, hf_cops_flags, tvb, offset, 1, ver_flags);
940     offset++;
941
942     proto_tree_add_item(cops_tree, hf_cops_op_code, tvb, offset, 1, FALSE);
943     offset ++;
944     proto_tree_add_item(cops_tree, hf_cops_client_type, tvb, offset, 2, FALSE);
945     offset += 2;
946
947     msg_len = tvb_get_ntohl(tvb, offset);
948     proto_tree_add_uint(cops_tree, hf_cops_msg_len, tvb, offset, 4, msg_len);
949     offset += 4;
950
951     while (tvb_reported_length_remaining(tvb, offset) >= COPS_OBJECT_HDR_SIZE) {
952       object_len = dissect_cops_object(tvb, pinfo, op_code, offset, cops_tree, client_type);
953       if (object_len < 0)
954         return;
955       offset += object_len;
956     }
957
958     garbage = tvb_length_remaining(tvb, offset);
959     if (garbage > 0)
960       proto_tree_add_text(cops_tree, tvb, offset, garbage,
961                           "Trailing garbage: %d byte%s", garbage,
962                           plurality(garbage, "", "s"));
963   }
964 }
965
966 static const char *cops_c_type_to_str(guint8 c_num, guint8 c_type)
967 {
968   switch (c_num) {
969   case COPS_OBJ_HANDLE:
970     if (c_type == 1)
971       return "Client Handle";
972     break;
973   case COPS_OBJ_IN_INT:
974   case COPS_OBJ_OUT_INT:
975     if (c_type == 1)
976       return "IPv4 Address + Interface";
977     else if (c_type == 2)
978       return "IPv6 Address + Interface";
979     break;
980   case COPS_OBJ_DECISION:
981   case COPS_OBJ_LPDPDECISION:
982     if (c_type == 1)
983       return "Decision Flags (Mandatory)";
984     else if (c_type == 2)
985       return "Stateless Data";
986     else if (c_type == 3)
987       return "Replacement Data";
988     else if (c_type == 4)
989       return "Client Specific Decision Data";
990     else if (c_type == 5)
991       return "Named Decision Data";
992     break;
993   case COPS_OBJ_CLIENTSI:
994     if (c_type == 1)
995       return "Signaled ClientSI";
996     else if (c_type == 2)
997       return "Named ClientSI";
998     break;
999   case COPS_OBJ_KATIMER:
1000     if (c_type == 1)
1001       return "Keep-alive timer value";
1002     break;
1003   case COPS_OBJ_PDPREDIRADDR:
1004   case COPS_OBJ_LASTPDPADDR:
1005     if (c_type == 1)
1006       return "IPv4 Address + TCP Port";
1007     else if (c_type == 2)
1008       return "IPv6 Address + TCP Port";
1009     break;
1010   case COPS_OBJ_ACCTTIMER:
1011     if (c_type == 1)
1012       return "Accounting timer value";
1013     break;
1014   case COPS_OBJ_INTEGRITY:
1015     if (c_type == 1)
1016       return "HMAC digest";
1017     break;
1018   }
1019
1020   return "";
1021 }
1022
1023 static int dissect_cops_object(tvbuff_t *tvb, packet_info *pinfo, guint8 op_code, guint32 offset, proto_tree *tree, guint16 client_type)
1024 {
1025   int object_len, contents_len;
1026   guint8 c_num, c_type;
1027   proto_item *ti;
1028   proto_tree *obj_tree;
1029   const char *type_str;
1030
1031   object_len = tvb_get_ntohs(tvb, offset);
1032   if (object_len < COPS_OBJECT_HDR_SIZE) {
1033     /* Bogus! */
1034     proto_tree_add_text(tree, tvb, offset, 2,
1035                         "Bad COPS object length: %u, should be at least %u",
1036                         object_len, COPS_OBJECT_HDR_SIZE);
1037     return -1;
1038   }
1039   c_num = tvb_get_guint8(tvb, offset + 2);
1040   c_type = tvb_get_guint8(tvb, offset + 3);
1041
1042   ti = proto_tree_add_uint_format(tree, hf_cops_obj_c_num, tvb, offset, object_len, c_num,
1043                                   "%s: %s", val_to_str(c_num, cops_c_num_vals, "Unknown"),
1044                                   cops_c_type_to_str(c_num, c_type));
1045   obj_tree = proto_item_add_subtree(ti, ett_cops_obj);
1046
1047   proto_tree_add_uint(obj_tree, hf_cops_obj_len, tvb, offset, 2, object_len);
1048   offset += 2;
1049
1050   proto_tree_add_uint(obj_tree, hf_cops_obj_c_num, tvb, offset, 1, c_num);
1051   offset++;
1052
1053   type_str = cops_c_type_to_str(c_num, c_type);
1054   proto_tree_add_uint_format_value(obj_tree, hf_cops_obj_c_type, tvb, offset, 1, c_type,
1055                       "%s%s%u%s",
1056                       type_str,
1057                       strlen(type_str) ? " (" : "",
1058                       c_type,
1059                       strlen(type_str) ? ")" : "");
1060   offset++;
1061
1062   contents_len = object_len - COPS_OBJECT_HDR_SIZE;
1063   dissect_cops_object_data(tvb, pinfo, offset, obj_tree, op_code, client_type, c_num, c_type, contents_len);
1064
1065   /* Pad to 32bit boundary */
1066   if (object_len % sizeof (guint32))
1067     object_len += (sizeof (guint32) - object_len % sizeof (guint32));
1068
1069   return object_len;
1070 }
1071
1072 static void dissect_cops_pr_objects(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree, int pr_len,
1073                                                                         oid_info_t** oid_info_p, guint32** pprid_subids_p, guint* pprid_subids_len_p)
1074 {
1075   int object_len, contents_len;
1076   guint8 s_num, s_type;
1077   const char *type_str;
1078   int ret;
1079   proto_tree *cops_pr_tree, *obj_tree;
1080   proto_item *ti;
1081
1082   cops_pr_tree = proto_item_add_subtree(tree, ett_cops_pr_obj);
1083
1084   while (pr_len >= COPS_OBJECT_HDR_SIZE) {
1085     object_len = tvb_get_ntohs(tvb, offset);
1086     if (object_len < COPS_OBJECT_HDR_SIZE) {
1087       /* Bogus! */
1088       proto_tree_add_text(tree, tvb, offset, 2,
1089                           "Bad COPS PR object length: %u, should be at least %u",
1090                           object_len, COPS_OBJECT_HDR_SIZE);
1091       return;
1092     }
1093     s_num = tvb_get_guint8(tvb, offset + 2);
1094
1095     ti = proto_tree_add_uint_format(cops_pr_tree, hf_cops_obj_s_num, tvb, offset, object_len, s_num,
1096                                     "%s", val_to_str(s_num, cops_s_num_vals, "Unknown"));
1097     obj_tree = proto_item_add_subtree(ti, ett_cops_pr_obj);
1098
1099     proto_tree_add_uint(obj_tree, hf_cops_obj_len, tvb, offset, 2, object_len);
1100     offset += 2;
1101     pr_len -= 2;
1102
1103     proto_tree_add_uint(obj_tree, hf_cops_obj_s_num, tvb, offset, 1, s_num);
1104     offset++;
1105     pr_len--;
1106
1107     s_type = tvb_get_guint8(tvb, offset);
1108     type_str = val_to_str(s_type, cops_s_type_vals, "Unknown");
1109     proto_tree_add_text(obj_tree, tvb, offset, 1, "S-Type: %s%s%u%s",
1110                         type_str,
1111                         strlen(type_str) ? " (" : "",
1112                         s_type,
1113                         strlen(type_str) ? ")" : "");
1114     offset++;
1115     pr_len--;
1116
1117     contents_len = object_len - COPS_OBJECT_HDR_SIZE;
1118     ret = dissect_cops_pr_object_data(tvb, pinfo, offset, obj_tree, s_num, s_type, contents_len,
1119                                                                           oid_info_p, pprid_subids_p, pprid_subids_len_p);
1120     if (ret < 0)
1121       break;
1122
1123     /* Pad to 32bit boundary */
1124     if (object_len % sizeof (guint32))
1125       object_len += (sizeof (guint32) - object_len % sizeof (guint32));
1126
1127     pr_len -= object_len - COPS_OBJECT_HDR_SIZE;
1128     offset += object_len - COPS_OBJECT_HDR_SIZE;
1129   }
1130 }
1131
1132 static void dissect_cops_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree,
1133                                      guint8 op_code, guint16 client_type, guint8 c_num, guint8 c_type, int len)
1134 {
1135   proto_item *ti;
1136   proto_tree *r_type_tree, *itf_tree, *reason_tree, *dec_tree, *error_tree, *clientsi_tree, *pdp_tree;
1137   guint16 r_type, m_type, reason, reason_sub, cmd_code, cmd_flags, error, error_sub, tcp_port;
1138   guint32 ipv4addr, ifindex;
1139   struct e_in6_addr ipv6addr;
1140   oid_info_t* oid_info = NULL;
1141   guint32* pprid_subids = NULL;
1142   guint pprid_subids_len = 0;
1143
1144   switch (c_num) {
1145   case COPS_OBJ_CONTEXT:
1146     r_type = tvb_get_ntohs(tvb, offset);
1147     m_type = tvb_get_ntohs(tvb, offset + 2);
1148     ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: R-Type: %s, M-Type: %u",
1149                              val_to_str(r_type, cops_r_type_vals, "Unknown"),
1150                              m_type);
1151
1152     r_type_tree = proto_item_add_subtree(ti, ett_cops_r_type_flags);
1153     proto_tree_add_uint(r_type_tree, hf_cops_r_type_flags, tvb, offset, 2, r_type);
1154     offset += 2;
1155     proto_tree_add_uint(r_type_tree, hf_cops_m_type_flags, tvb, offset, 2, m_type);
1156
1157     break;
1158   case COPS_OBJ_IN_INT:
1159   case COPS_OBJ_OUT_INT:
1160     if (c_type == 1) {          /* IPv4 */
1161       ipv4addr = tvb_get_ipv4(tvb, offset);
1162       ifindex = tvb_get_ntohl(tvb, offset + 4);
1163       ti = proto_tree_add_text(tree, tvb, offset, 8, "Contents: IPv4 address %s, ifIndex: %u",
1164                                ip_to_str((guint8 *)&ipv4addr), ifindex);
1165       itf_tree = proto_item_add_subtree(ti, ett_cops_itf);
1166       proto_tree_add_ipv4(itf_tree,
1167                           (c_num == COPS_OBJ_IN_INT) ? hf_cops_in_int_ipv4 : hf_cops_out_int_ipv4,
1168                           tvb, offset, 4, ipv4addr);
1169       offset += 4;
1170     } else if (c_type == 2) {   /* IPv6 */
1171       tvb_get_ipv6(tvb, offset, &ipv6addr);
1172       ifindex = tvb_get_ntohl(tvb, offset + sizeof ipv6addr);
1173       ti = proto_tree_add_text(tree, tvb, offset, 20, "Contents: IPv6 address %s, ifIndex: %u",
1174                                ip6_to_str(&ipv6addr), ifindex);
1175       itf_tree = proto_item_add_subtree(ti, ett_cops_itf);
1176       proto_tree_add_ipv6(itf_tree,
1177                           (c_num == COPS_OBJ_IN_INT) ? hf_cops_in_int_ipv6 : hf_cops_out_int_ipv6,
1178                           tvb, offset, 16, (guint8 *)&ipv6addr);
1179       offset += 16;
1180     } else {
1181       break;
1182     }
1183     proto_tree_add_uint(itf_tree, hf_cops_int_ifindex, tvb, offset, 4, ifindex);
1184
1185     break;
1186   case COPS_OBJ_REASON:
1187     reason = tvb_get_ntohs(tvb, offset);
1188     reason_sub = tvb_get_ntohs(tvb, offset + 2);
1189     ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: Reason-Code: %s, Reason Sub-code: 0x%04x",
1190                              val_to_str(reason, cops_reason_vals, "<Unknown value>"), reason_sub);
1191     reason_tree = proto_item_add_subtree(ti, ett_cops_reason);
1192     proto_tree_add_uint(reason_tree, hf_cops_reason, tvb, offset, 2, reason);
1193     offset += 2;
1194     if (reason == 13) {
1195       proto_tree_add_text(reason_tree, tvb, offset, 2, "Reason Sub-code: "
1196                           "Unknown object's C-Num %u, C-Type %u",
1197                           tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset + 1));
1198     } else
1199       proto_tree_add_uint(reason_tree, hf_cops_reason_sub, tvb, offset, 2, reason_sub);
1200
1201     break;
1202   case COPS_OBJ_DECISION:
1203   case COPS_OBJ_LPDPDECISION:
1204     if (c_type == 1) {
1205       cmd_code = tvb_get_ntohs(tvb, offset);
1206       cmd_flags = tvb_get_ntohs(tvb, offset + 2);
1207       ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: Command-Code: %s, Flags: %s",
1208                                val_to_str(cmd_code, cops_dec_cmd_code_vals, "<Unknown value>"),
1209                                val_to_str(cmd_flags, cops_dec_cmd_flag_vals, "<Unknown flag>"));
1210       dec_tree = proto_item_add_subtree(ti, ett_cops_decision);
1211       proto_tree_add_uint(dec_tree, hf_cops_dec_cmd_code, tvb, offset, 2, cmd_code);
1212       offset += 2;
1213       proto_tree_add_uint(dec_tree, hf_cops_dec_flags, tvb, offset, 2, cmd_flags);
1214     } else if (c_type == 5) { /*COPS-PR Data*/
1215       ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: %d bytes", len);
1216       dec_tree = proto_item_add_subtree(ti, ett_cops_decision);
1217       dissect_cops_pr_objects(tvb, pinfo, offset, dec_tree, len, &oid_info, &pprid_subids, &pprid_subids_len);
1218     }
1219
1220     /* PacketCable : Analyze the remaining data if available */
1221     if (client_type == COPS_CLIENT_PC_DQOS && c_type == 4) {
1222         cops_analyze_packetcable_dqos_obj(tvb, pinfo, tree, op_code, offset);
1223     } else if (client_type == COPS_CLIENT_PC_MM && c_type == 4) {
1224         cops_analyze_packetcable_mm_obj(tvb, pinfo, tree, op_code, offset);
1225     }
1226
1227     break;
1228   case COPS_OBJ_ERROR:
1229     if (c_type != 1)
1230       break;
1231
1232     error = tvb_get_ntohs(tvb, offset);
1233     error_sub = tvb_get_ntohs(tvb, offset + 2);
1234     ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: Error-Code: %s, Error Sub-code: 0x%04x",
1235                              val_to_str(error, cops_error_vals, "<Unknown value>"), error_sub);
1236     error_tree = proto_item_add_subtree(ti, ett_cops_error);
1237     proto_tree_add_uint(error_tree, hf_cops_error, tvb, offset, 2, error);
1238     offset += 2;
1239     if (error == 13) {
1240       proto_tree_add_text(error_tree, tvb, offset, 2, "Error Sub-code: "
1241                           "Unknown object's C-Num %u, C-Type %u",
1242                           tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset + 1));
1243     } else
1244       proto_tree_add_uint(error_tree, hf_cops_error_sub, tvb, offset, 2, error_sub);
1245
1246     break;
1247   case COPS_OBJ_CLIENTSI:
1248
1249     /* For PacketCable */
1250     if (client_type == COPS_CLIENT_PC_DQOS && c_type == 1) {
1251        cops_analyze_packetcable_dqos_obj(tvb, pinfo, tree, op_code, offset);
1252        break;
1253     } else if (client_type == COPS_CLIENT_PC_MM && c_type == 1) {
1254        cops_analyze_packetcable_mm_obj(tvb, pinfo, tree, op_code, offset);
1255        break;
1256     }
1257
1258     if (c_type != 2) /*Not COPS-PR data*/
1259       break;
1260
1261     ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: %d bytes", len);
1262     clientsi_tree = proto_item_add_subtree(ti, ett_cops_clientsi);
1263
1264     dissect_cops_pr_objects(tvb, pinfo, offset, clientsi_tree, len, &oid_info, &pprid_subids, &pprid_subids_len);
1265
1266     break;
1267   case COPS_OBJ_KATIMER:
1268     if (c_type != 1)
1269       break;
1270
1271     proto_tree_add_item(tree, hf_cops_katimer, tvb, offset + 2, 2, FALSE);
1272     if (tvb_get_ntohs(tvb, offset + 2) == 0)
1273       proto_tree_add_text(tree, tvb, offset, 0, "Value of zero implies infinity.");
1274
1275     break;
1276   case COPS_OBJ_PEPID:
1277     if (c_type != 1)
1278       break;
1279
1280     if (tvb_strnlen(tvb, offset, len) == -1) {
1281       proto_item *pep_ti;
1282       pep_ti = proto_tree_add_text(tree, tvb, offset, len, "PEP Id is not a NULL terminated ASCII string");
1283       expert_add_info_format(pinfo, pep_ti, PI_MALFORMED, PI_NOTE,
1284                              "PEP Id is not a NULL terminated ASCII string");
1285       PROTO_ITEM_SET_GENERATED(pep_ti);
1286     }
1287     else
1288       proto_tree_add_item(tree, hf_cops_pepid, tvb, offset,
1289                           tvb_strnlen(tvb, offset, len) + 1, FALSE);
1290
1291     break;
1292   case COPS_OBJ_REPORT_TYPE:
1293     if (c_type != 1)
1294       break;
1295
1296     proto_tree_add_item(tree, hf_cops_report_type, tvb, offset, 2, FALSE);
1297
1298     break;
1299   case COPS_OBJ_PDPREDIRADDR:
1300   case COPS_OBJ_LASTPDPADDR:
1301     if (c_type == 1) {          /* IPv4 */
1302       ipv4addr = tvb_get_ipv4(tvb, offset);
1303       tcp_port = tvb_get_ntohs(tvb, offset + 4 + 2);
1304       ti = proto_tree_add_text(tree, tvb, offset, 8, "Contents: IPv4 address %s, TCP Port Number: %u",
1305                                ip_to_str((guint8 *)&ipv4addr), tcp_port);
1306       pdp_tree = proto_item_add_subtree(ti, ett_cops_pdp);
1307       proto_tree_add_ipv4(pdp_tree,
1308                           (c_num == COPS_OBJ_PDPREDIRADDR) ? hf_cops_pdprediraddr_ipv4 : hf_cops_lastpdpaddr_ipv4,
1309                           tvb, offset, 4, ipv4addr);
1310       offset += 4;
1311     } else if (c_type == 2) {   /* IPv6 */
1312       tvb_get_ipv6(tvb, offset, &ipv6addr);
1313       tcp_port = tvb_get_ntohs(tvb, offset + sizeof ipv6addr + 2);
1314       ti = proto_tree_add_text(tree, tvb, offset, 20, "Contents: IPv6 address %s, TCP Port Number: %u",
1315                                ip6_to_str(&ipv6addr), tcp_port);
1316       pdp_tree = proto_item_add_subtree(ti, ett_cops_pdp);
1317       proto_tree_add_ipv6(pdp_tree,
1318                           (c_num == COPS_OBJ_PDPREDIRADDR) ? hf_cops_pdprediraddr_ipv6 : hf_cops_lastpdpaddr_ipv6,
1319                           tvb, offset, 16, (guint8 *)&ipv6addr);
1320       offset += 16;
1321     } else {
1322       break;
1323     }
1324     offset += 2;
1325     proto_tree_add_uint(pdp_tree, hf_cops_pdp_tcp_port, tvb, offset, 2, tcp_port);
1326
1327     break;
1328   case COPS_OBJ_ACCTTIMER:
1329     if (c_type != 1)
1330       break;
1331
1332     proto_tree_add_item(tree, hf_cops_accttimer, tvb, offset + 2, 2, FALSE);
1333     if (tvb_get_ntohs(tvb, offset + 2) == 0)
1334       proto_tree_add_text(tree, tvb, offset, 0, "Value of zero means "
1335                           "there SHOULD be no unsolicited accounting updates.");
1336
1337     break;
1338   case COPS_OBJ_INTEGRITY:
1339     if (c_type != 1)
1340       break;      /* Not HMAC digest */
1341
1342     proto_tree_add_item(tree, hf_cops_key_id, tvb, offset, 4, FALSE);
1343     proto_tree_add_item(tree, hf_cops_seq_num, tvb, offset + 4, 4, FALSE);
1344     proto_tree_add_text(tree, tvb, offset + 8 , len - 8, "Contents: Keyed Message Digest");
1345
1346     break;
1347   default:
1348     proto_tree_add_text(tree, tvb, offset, len, "Contents: %d bytes", len);
1349
1350     break;
1351   }
1352 }
1353
1354 static guint redecode_oid(guint32* pprid_subids, guint pprid_subids_len, guint8* encoded_subids, guint encoded_len, guint32** subids_p) {
1355         guint i;
1356         guint n = 0;
1357         guint32 subid = 0;
1358         guint32* subids;
1359         guint32* subid_overflow;
1360
1361         for (i=0; i<encoded_len; i++) { if (! (encoded_subids[i] & 0x80 )) n++; }
1362
1363         *subids_p = subids = ep_alloc(sizeof(guint32)*(n+pprid_subids_len));
1364         subid_overflow = subids+n+pprid_subids_len;
1365         for (i=0;i<pprid_subids_len;i++) subids[i] = pprid_subids[i];
1366
1367         subids += pprid_subids_len;
1368
1369
1370         for (i=0; i<encoded_len; i++){
1371                 guint8 byte = encoded_subids[i];
1372
1373                 subid <<= 7;
1374                 subid |= byte & 0x7F;
1375
1376                 if (byte & 0x80) {
1377                         continue;
1378                 }
1379
1380                 DISSECTOR_ASSERT(subids < subid_overflow);
1381                 *subids++ = subid;
1382                 subid = 0;
1383         }
1384
1385         return pprid_subids_len+n;
1386 }
1387
1388
1389 static int dissect_cops_pr_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree,
1390                                                                            guint8 s_num, guint8 s_type, int len,
1391                                                                            oid_info_t** oid_info_p, guint32** pprid_subids, guint* pprid_subids_len) {
1392   proto_item *ti;
1393   proto_tree *asn_tree, *gperror_tree, *cperror_tree;
1394   guint16 gperror=0, gperror_sub=0, cperror=0, cperror_sub=0;
1395   asn1_ctx_t actx;
1396
1397   memset(&actx,0,sizeof(actx));
1398   actx.pinfo = pinfo;
1399
1400   switch (s_num){
1401           case COPS_OBJ_PPRID: {
1402                   tvbuff_t* oid_tvb = NULL;
1403
1404                   if (s_type != 1) /* Not Prefix Provisioning Instance Identifier (PPRID) */
1405                           break;
1406                   /* Never tested this branch */
1407                   ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
1408                   asn_tree = proto_item_add_subtree(ti, ett_cops_asn1);
1409
1410                   offset = dissect_ber_object_identifier(FALSE, &actx, asn_tree, tvb, offset, hf_cops_pprid_oid, &oid_tvb);
1411
1412                   if (oid_tvb) {
1413                           guint encoid_len = tvb_length_remaining(oid_tvb,0);
1414                           guint8* encoid = ep_tvb_memdup(oid_tvb,0,encoid_len);
1415
1416                           (*pprid_subids_len) = oid_encoded2subid(encoid, encoid_len, pprid_subids);
1417                   }
1418                   break;
1419           }
1420           case COPS_OBJ_PRID: {
1421                   guint32* subids;
1422                   guint subids_len;
1423                   guint matched;
1424                   guint left;
1425                   gint8 ber_class;
1426                   gboolean ber_pc;
1427                   gint32 ber_tag;
1428                   guint encoid_len;
1429                   guint8* encoid;
1430                   oid_info_t* oid_info;
1431
1432                   if (s_type != 1) break; /* Not Provisioning Instance Identifier (PRID) */
1433
1434                   ti=proto_tree_add_text(tree, tvb, offset, len, "Contents:");
1435                   asn_tree = proto_item_add_subtree(ti, ett_cops_asn1);
1436
1437                   offset = get_ber_identifier(tvb, offset, &ber_class, &ber_pc, &ber_tag);
1438                   offset = get_ber_length(tvb, offset, &encoid_len, NULL);
1439
1440                   /* TODO: check pc, class and tag */
1441
1442                   encoid = ep_tvb_memdup(tvb,offset,encoid_len);
1443
1444                   if (*pprid_subids) {
1445                           /* Never tested this branch */
1446                           subids_len = redecode_oid(*pprid_subids, *pprid_subids_len, encoid, encoid_len, &subids);
1447                           encoid_len = oid_subid2encoded(subids_len, subids, &encoid);
1448                   } else {
1449                           subids_len = oid_encoded2subid(encoid, encoid_len, &subids);
1450                   }
1451
1452                   proto_tree_add_oid(asn_tree,hf_cops_prid_oid,tvb,offset,encoid_len,encoid);
1453
1454                   oid_info = oid_get(subids_len, subids, &matched, &left);
1455
1456                   /*
1457                      TODO: from RFC 3159 find-out how the values are mapped,
1458                            when instead of an oid for an xxEntry
1459                            we have one decribing a scalar or something else,
1460                            what's bellow works in most cases but is not complete.
1461                    */
1462                   if (left <= 1 && oid_info->kind == OID_KIND_ROW) {
1463                           *oid_info_p = oid_info;
1464                   } else {
1465                           *oid_info_p = NULL;
1466                   }
1467
1468                   break;
1469           }
1470           case COPS_OBJ_EPD: {
1471                   oid_info_t* oid_info;
1472                   guint end_offset = offset + len;
1473
1474                   if (s_type != 1) break;/* Not Encoded Provisioning Instance Data (EPD) */
1475
1476                   ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
1477                   asn_tree = proto_item_add_subtree(ti, ett_cops_asn1);
1478
1479                   /*
1480                    * XXX: LAZYNESS WARNING:
1481                    * We are assuming that for the first element in the sequence
1482                    * that describes an entry subid==1, and, that the subsequent elements
1483                    * use ++subid; This is true for all IETF's PIBs (and good sense
1484                    * indicates it should be this way) but AFAIK there's nothing in
1485                    * SMIv2 that imposes this restriction.  -- a lazy lego
1486                    */
1487
1488                   if(*oid_info_p) {
1489                           if ((*oid_info_p)->kind == OID_KIND_ROW) {
1490                                   oid_info = emem_tree_lookup32((*oid_info_p)->children,1);
1491                           } else {
1492                                   oid_info = NULL;
1493                           }
1494                   } else {
1495                           oid_info = NULL;
1496                   }
1497
1498
1499                   while(offset < end_offset) {
1500                           gint8 ber_class;
1501                           gboolean ber_pc;
1502                           gint32 ber_tag;
1503                           guint32 ber_length;
1504                           gboolean ber_ind;
1505
1506                           offset = get_ber_identifier(tvb, offset, &ber_class, &ber_pc, &ber_tag);
1507                           offset = get_ber_length(tvb, offset, &ber_length, &ber_ind);
1508
1509                           if (oid_info) {
1510                                   /*
1511                                    * XXX: LAZYNESS WARNING:
1512                                    * We are assuming that the value of the sequenced item is of
1513                                    * the right class, the right type and the right legth.
1514                                    * We should check that to avoid throwing a Malformed packet and
1515                                    * keep dissecting.
1516                                    * We should verify the class and the tag match what we expect as well,
1517                                    * but COPS and SNMP use different tags (&#@$!) so the typedata in oid_info_t
1518                                    * does not work here.
1519                                    * -- a lazy lego
1520                                    */
1521
1522                                   proto_tree_add_item(asn_tree,oid_info->value_hfid,tvb,offset,ber_length,FALSE);
1523
1524                                   oid_info = emem_tree_lookup32((*oid_info_p)->children,oid_info->subid+1);
1525                           } else {
1526                                   int hfid = cops_tag_cls2syntax( ber_tag, ber_class );
1527                                   proto_tree_add_item(asn_tree,hfid,tvb,offset,ber_length,FALSE);
1528                           }
1529
1530                           offset += ber_length;
1531                   }
1532
1533                   (*oid_info_p) = NULL;
1534                   break;
1535           }
1536           case COPS_OBJ_ERRPRID: {
1537                   if (s_type != 1) break; /*Not  Error Provisioning Instance Identifier (ErrorPRID)*/
1538
1539                   ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
1540                   asn_tree = proto_item_add_subtree(ti, ett_cops_asn1);
1541
1542                   offset = dissect_ber_object_identifier(FALSE, &actx, asn_tree, tvb, offset, hf_cops_errprid_oid, NULL);
1543
1544                   break;
1545           }
1546   case COPS_OBJ_GPERR:
1547     if (s_type != 1) /* Not Global Provisioning Error Object (GPERR) */
1548       break;
1549
1550     gperror = tvb_get_ntohs(tvb, offset);
1551     gperror_sub = tvb_get_ntohs(tvb, offset + 2);
1552     ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: Error-Code: %s, Error Sub-code: 0x%04x",
1553                        val_to_str(gperror, cops_gperror_vals, "<Unknown value>"), gperror_sub);
1554     gperror_tree = proto_item_add_subtree(ti, ett_cops_gperror);
1555     proto_tree_add_uint(gperror_tree, hf_cops_gperror, tvb, offset, 2, gperror);
1556     offset += 2;
1557     if (gperror == 13) {
1558       proto_tree_add_text(gperror_tree, tvb, offset, 2, "Error Sub-code: "
1559                           "Unknown object's C-Num %u, C-Type %u",
1560                           tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset + 1));
1561     } else
1562       proto_tree_add_uint(gperror_tree, hf_cops_gperror_sub, tvb, offset, 2, gperror_sub);
1563
1564     break;
1565   case COPS_OBJ_CPERR:
1566     if (s_type != 1) /*Not PRC Class Provisioning Error Object (CPERR) */
1567       break;
1568
1569     cperror = tvb_get_ntohs(tvb, offset);
1570     cperror_sub = tvb_get_ntohs(tvb, offset + 2);
1571     ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: Error-Code: %s, Error Sub-code: 0x%04x",
1572                        val_to_str(cperror, cops_cperror_vals, "<Unknown value>"), cperror_sub);
1573     cperror_tree = proto_item_add_subtree(ti, ett_cops_cperror);
1574     proto_tree_add_uint(cperror_tree, hf_cops_cperror, tvb, offset, 2, cperror);
1575     offset += 2;
1576     if (cperror == 13) {
1577       proto_tree_add_text(cperror_tree, tvb, offset, 2, "Error Sub-code: "
1578                           "Unknown object's S-Num %u, C-Type %u",
1579                           tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset + 1));
1580     } else
1581       proto_tree_add_uint(cperror_tree, hf_cops_cperror_sub, tvb, offset, 2, cperror_sub);
1582
1583     break;
1584   default:
1585     proto_tree_add_text(tree, tvb, offset, len, "Contents: %d bytes", len);
1586     break;
1587   }
1588
1589   return 0;
1590 }
1591
1592
1593 /* Register the protocol with Wireshark */
1594 void proto_register_cops(void)
1595 {
1596   /* Setup list of header fields */
1597   static hf_register_info hf[] = {
1598     { &hf_cops_ver_flags,
1599       { "Version and Flags",           "cops.ver_flags",
1600       FT_UINT8, BASE_HEX, NULL, 0x0,
1601       "Version and Flags in COPS Common Header", HFILL }
1602     },
1603     { &hf_cops_version,
1604       { "Version",           "cops.version",
1605       FT_UINT8, BASE_DEC, NULL, 0xF0,
1606       "Version in COPS Common Header", HFILL }
1607     },
1608     { &hf_cops_flags,
1609       { "Flags",           "cops.flags",
1610       FT_UINT8, BASE_HEX, VALS(cops_flags_vals), 0x0F,
1611       "Flags in COPS Common Header", HFILL }
1612     },
1613     { &hf_cops_op_code,
1614       { "Op Code",           "cops.op_code",
1615       FT_UINT8, BASE_DEC, VALS(cops_op_code_vals), 0x0,
1616       "Op Code in COPS Common Header", HFILL }
1617     },
1618     { &hf_cops_client_type,
1619       { "Client Type",           "cops.client_type",
1620       FT_UINT16, BASE_DEC, VALS(cops_client_type_vals), 0x0,
1621       "Client Type in COPS Common Header", HFILL }
1622     },
1623     { &hf_cops_msg_len,
1624       { "Message Length",           "cops.msg_len",
1625       FT_UINT32, BASE_DEC, NULL, 0x0,
1626       "Message Length in COPS Common Header", HFILL }
1627     },
1628     { &hf_cops_obj_len,
1629       { "Object Length",           "cops.obj.len",
1630       FT_UINT32, BASE_DEC, NULL, 0x0,
1631       "Object Length in COPS Object Header", HFILL }
1632     },
1633     { &hf_cops_obj_c_num,
1634       { "C-Num",           "cops.c_num",
1635       FT_UINT8, BASE_DEC, VALS(cops_c_num_vals), 0x0,
1636       "C-Num in COPS Object Header", HFILL }
1637     },
1638     { &hf_cops_obj_c_type,
1639       { "C-Type",           "cops.c_type",
1640       FT_UINT8, BASE_DEC, NULL, 0x0,
1641       "C-Type in COPS Object Header", HFILL }
1642     },
1643
1644     { &hf_cops_obj_s_num,
1645       { "S-Num",           "cops.s_num",
1646       FT_UINT8, BASE_DEC, VALS(cops_s_num_vals), 0x0,
1647       "S-Num in COPS-PR Object Header", HFILL }
1648     },
1649     { &hf_cops_obj_s_type,
1650       { "S-Type",           "cops.s_type",
1651       FT_UINT8, BASE_DEC, NULL, 0x0,
1652       "S-Type in COPS-PR Object Header", HFILL }
1653     },
1654
1655     { &hf_cops_r_type_flags,
1656       { "R-Type",           "cops.context.r_type",
1657       FT_UINT16, BASE_HEX, VALS(cops_r_type_vals), 0xFFFF,
1658       "R-Type in COPS Context Object", HFILL }
1659     },
1660     { &hf_cops_m_type_flags,
1661       { "M-Type",           "cops.context.m_type",
1662       FT_UINT16, BASE_HEX, NULL, 0xFFFF,
1663       "M-Type in COPS Context Object", HFILL }
1664     },
1665     { &hf_cops_in_int_ipv4,
1666       { "IPv4 address",           "cops.in-int.ipv4",
1667       FT_IPv4, BASE_NONE, NULL, 0,
1668       "IPv4 address in COPS IN-Int object", HFILL }
1669     },
1670     { &hf_cops_in_int_ipv6,
1671       { "IPv6 address",           "cops.in-int.ipv6",
1672       FT_IPv6, BASE_NONE, NULL, 0,
1673       "IPv6 address in COPS IN-Int object", HFILL }
1674     },
1675     { &hf_cops_out_int_ipv4,
1676       { "IPv4 address",           "cops.out-int.ipv4",
1677       FT_IPv4, BASE_NONE, NULL, 0,
1678       "IPv4 address in COPS OUT-Int object", HFILL }
1679     },
1680     { &hf_cops_out_int_ipv6,
1681       { "IPv6 address",           "cops.out-int.ipv6",
1682       FT_IPv6, BASE_NONE, NULL, 0,
1683       "IPv6 address in COPS OUT-Int", HFILL }
1684     },
1685     { &hf_cops_int_ifindex,
1686       { "ifIndex",           "cops.in-out-int.ifindex",
1687       FT_UINT32, BASE_DEC, NULL, 0x0,
1688       "If SNMP is supported, corresponds to MIB-II ifIndex", HFILL }
1689     },
1690     { &hf_cops_reason,
1691       { "Reason",           "cops.reason",
1692       FT_UINT16, BASE_DEC, VALS(cops_reason_vals), 0,
1693       "Reason in Reason object", HFILL }
1694     },
1695     { &hf_cops_reason_sub,
1696       { "Reason Sub-code",           "cops.reason_sub",
1697       FT_UINT16, BASE_HEX, NULL, 0,
1698       "Reason Sub-code in Reason object", HFILL }
1699     },
1700     { &hf_cops_dec_cmd_code,
1701       { "Command-Code",           "cops.decision.cmd",
1702       FT_UINT16, BASE_DEC, VALS(cops_dec_cmd_code_vals), 0,
1703       "Command-Code in Decision/LPDP Decision object", HFILL }
1704     },
1705     { &hf_cops_dec_flags,
1706       { "Flags",           "cops.decision.flags",
1707       FT_UINT16, BASE_HEX, VALS(cops_dec_cmd_flag_vals), 0xffff,
1708       "Flags in Decision/LPDP Decision object", HFILL }
1709     },
1710     { &hf_cops_error,
1711       { "Error",           "cops.error",
1712       FT_UINT16, BASE_DEC, VALS(cops_error_vals), 0,
1713       "Error in Error object", HFILL }
1714     },
1715     { &hf_cops_error_sub,
1716       { "Error Sub-code",           "cops.error_sub",
1717       FT_UINT16, BASE_HEX, NULL, 0,
1718       "Error Sub-code in Error object", HFILL }
1719     },
1720     { &hf_cops_katimer,
1721       { "Contents: KA Timer Value",           "cops.katimer.value",
1722       FT_UINT16, BASE_DEC, NULL, 0,
1723       "Keep-Alive Timer Value in KATimer object", HFILL }
1724     },
1725     { &hf_cops_pepid,
1726       { "Contents: PEP Id",           "cops.pepid.id",
1727       FT_STRING, BASE_NONE, NULL, 0,
1728       "PEP Id in PEPID object", HFILL }
1729     },
1730     { &hf_cops_report_type,
1731       { "Contents: Report-Type",           "cops.report_type",
1732       FT_UINT16, BASE_DEC, VALS(cops_report_type_vals), 0,
1733       "Report-Type in Report-Type object", HFILL }
1734     },
1735     { &hf_cops_pdprediraddr_ipv4,
1736       { "IPv4 address",           "cops.pdprediraddr.ipv4",
1737       FT_IPv4, BASE_NONE, NULL, 0,
1738       "IPv4 address in COPS PDPRedirAddr object", HFILL }
1739     },
1740     { &hf_cops_pdprediraddr_ipv6,
1741       { "IPv6 address",           "cops.pdprediraddr.ipv6",
1742       FT_IPv6, BASE_NONE, NULL, 0,
1743       "IPv6 address in COPS PDPRedirAddr object", HFILL }
1744     },
1745     { &hf_cops_lastpdpaddr_ipv4,
1746       { "IPv4 address",           "cops.lastpdpaddr.ipv4",
1747       FT_IPv4, BASE_NONE, NULL, 0,
1748       "IPv4 address in COPS LastPDPAddr object", HFILL }
1749     },
1750     { &hf_cops_lastpdpaddr_ipv6,
1751       { "IPv6 address",           "cops.lastpdpaddr.ipv6",
1752       FT_IPv6, BASE_NONE, NULL, 0,
1753       "IPv6 address in COPS LastPDPAddr object", HFILL }
1754     },
1755     { &hf_cops_pdp_tcp_port,
1756       { "TCP Port Number",           "cops.pdp.tcp_port",
1757       FT_UINT32, BASE_DEC, NULL, 0x0,
1758        "TCP Port Number of PDP in PDPRedirAddr/LastPDPAddr object", HFILL }
1759     },
1760     { &hf_cops_accttimer,
1761       { "Contents: ACCT Timer Value",           "cops.accttimer.value",
1762       FT_UINT16, BASE_DEC, NULL, 0,
1763       "Accounting Timer Value in AcctTimer object", HFILL }
1764     },
1765     { &hf_cops_key_id,
1766       { "Contents: Key ID",           "cops.integrity.key_id",
1767       FT_UINT32, BASE_DEC, NULL, 0,
1768       "Key ID in Integrity object", HFILL }
1769     },
1770     { &hf_cops_seq_num,
1771       { "Contents: Sequence Number",           "cops.integrity.seq_num",
1772       FT_UINT32, BASE_DEC, NULL, 0,
1773       "Sequence Number in Integrity object", HFILL }
1774     },
1775     { &hf_cops_gperror,
1776       { "Error",           "cops.gperror",
1777       FT_UINT16, BASE_DEC, VALS(cops_gperror_vals), 0,
1778       "Error in Error object", HFILL }
1779     },
1780     { &hf_cops_gperror_sub,
1781       { "Error Sub-code",           "cops.gperror_sub",
1782       FT_UINT16, BASE_HEX, NULL, 0,
1783       "Error Sub-code in Error object", HFILL }
1784     },
1785     { &hf_cops_cperror,
1786       { "Error",           "cops.cperror",
1787       FT_UINT16, BASE_DEC, VALS(cops_cperror_vals), 0,
1788       "Error in Error object", HFILL }
1789     },
1790     { &hf_cops_cperror_sub,
1791       { "Error Sub-code",           "cops.cperror_sub",
1792       FT_UINT16, BASE_HEX, NULL, 0,
1793       "Error Sub-code in Error object", HFILL }
1794     },
1795   { &hf_cops_prid_oid, { "PRID Instance Identifier", "cops.prid.instance_id", FT_OID, BASE_NONE, NULL, 0, NULL, HFILL } },
1796   { &hf_cops_pprid_oid, { "Prefix Identifier", "cops.pprid.prefix_id", FT_OID, BASE_NONE, NULL, 0, NULL, HFILL } },
1797   { &hf_cops_errprid_oid, { "ErrorPRID Instance Identifier", "cops.errprid.instance_id", FT_OID, BASE_NONE, NULL, 0, NULL, HFILL } },
1798   { &hf_cops_epd_unknown, { "EPD Unknown Data", "cops.epd.unknown", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1799   { &hf_cops_epd_null, { "EPD Null Data", "cops.epd.null", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1800   { &hf_cops_epd_int, { "EPD Integer Data", "cops.epd.int", FT_INT64, BASE_DEC, NULL, 0, NULL, HFILL } },
1801   { &hf_cops_epd_octets, { "EPD Octet String Data", "cops.epd.octets", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1802   { &hf_cops_epd_oid, { "EPD OID Data", "cops.epd.oid", FT_OID, BASE_NONE, NULL, 0, NULL, HFILL } },
1803   { &hf_cops_epd_ipv4, { "EPD IPAddress Data", "cops.epd.ipv4", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
1804   { &hf_cops_epd_u32, { "EPD Unsigned32 Data", "cops.epd.unsigned32", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL } },
1805   { &hf_cops_epd_ticks, { "EPD TimeTicks Data", "cops.epd.timeticks", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL } },
1806   { &hf_cops_epd_opaque, { "EPD Opaque Data", "cops.epd.opaque", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1807   { &hf_cops_epd_i64, { "EPD Inetger64 Data", "cops.epd.integer64", FT_INT64, BASE_DEC, NULL, 0, NULL, HFILL } },
1808   { &hf_cops_epd_u64, { "EPD Unsigned64 Data", "cops.epd.unsigned64", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL } },
1809
1810     /* Added for PacketCable */
1811
1812     { &hf_cops_subtree,
1813       { "Object Subtree", "cops.pc_subtree",
1814         FT_NONE, BASE_NONE, NULL, 0,
1815         NULL, HFILL }
1816     },
1817     { &hf_cops_pc_ds_field,
1818       { "DS Field (DSCP or TOS)", "cops.pc_ds_field",
1819         FT_UINT8, BASE_HEX, NULL, 0x00,
1820         NULL, HFILL }
1821     },
1822     { &hf_cops_pc_direction,
1823       { "Direction", "cops.pc_direction",
1824         FT_UINT8, BASE_HEX, NULL, 0x00,
1825         NULL, HFILL }
1826     },
1827     { &hf_cops_pc_gate_spec_flags,
1828       { "Flags", "cops.pc_gate_spec_flags",
1829         FT_UINT8, BASE_HEX, NULL, 0x00,
1830         NULL, HFILL }
1831     },
1832     { &hf_cops_pc_protocol_id,
1833       { "Protocol ID", "cops.pc_protocol_id",
1834         FT_UINT8, BASE_HEX, NULL, 0x00,
1835         NULL, HFILL }
1836     },
1837     { &hf_cops_pc_session_class,
1838       { "Session Class", "cops.pc_session_class",
1839         FT_UINT8, BASE_HEX, NULL, 0x00,
1840         NULL, HFILL }
1841     },
1842     { &hf_cops_pc_algorithm,
1843       { "Algorithm", "cops.pc_algorithm",
1844         FT_UINT16, BASE_HEX, NULL, 0x00,
1845         NULL, HFILL }
1846     },
1847     { &hf_cops_pc_cmts_ip_port,
1848       { "CMTS IP Port", "cops.pc_cmts_ip_port",
1849         FT_UINT16, BASE_HEX, NULL, 0x00,
1850         NULL, HFILL }
1851     },
1852     { &hf_cops_pc_prks_ip_port,
1853       { "PRKS IP Port", "cops.pc_prks_ip_port",
1854         FT_UINT16, BASE_HEX, NULL, 0x00,
1855         NULL, HFILL }
1856     },
1857     { &hf_cops_pc_srks_ip_port,
1858       { "SRKS IP Port", "cops.pc_srks_ip_port",
1859         FT_UINT16, BASE_HEX, NULL, 0x00,
1860         NULL, HFILL }
1861     },
1862     { &hf_cops_pc_dest_port,
1863       { "Destination IP Port", "cops.pc_dest_port",
1864         FT_UINT16, BASE_HEX, NULL, 0x00,
1865         NULL, HFILL }
1866     },
1867     { &hf_cops_pc_packetcable_err_code,
1868       { "Error Code", "cops.pc_packetcable_err_code",
1869         FT_UINT16, BASE_HEX, NULL, 0x00,
1870         NULL, HFILL }
1871     },
1872     { &hf_cops_pc_packetcable_sub_code,
1873       { "Error Sub Code", "cops.pc_packetcable_sub_code",
1874         FT_UINT16, BASE_HEX, NULL, 0x00,
1875         NULL, HFILL }
1876     },
1877     { &hf_cops_pc_remote_flags,
1878       { "Flags", "cops.pc_remote_flags",
1879         FT_UINT16, BASE_HEX, NULL, 0x00,
1880         NULL, HFILL }
1881     },
1882     { &hf_cops_pc_close_subcode,
1883       { "Reason Sub Code", "cops.pc_close_subcode",
1884         FT_UINT16, BASE_HEX, NULL, 0x00,
1885         NULL, HFILL }
1886     },
1887     { &hf_cops_pc_gate_command_type,
1888       { "Gate Command Type", "cops.pc_gate_command_type",
1889         FT_UINT16, BASE_HEX, NULL, 0x00,
1890         NULL, HFILL }
1891     },
1892     { &hf_cops_pc_reason_code,
1893       { "Reason Code", "cops.pc_reason_code",
1894         FT_UINT16, BASE_HEX, NULL, 0x00,
1895         NULL, HFILL }
1896     },
1897     { &hf_cops_pc_delete_subcode,
1898       { "Reason Sub Code", "cops.pc_delete_subcode",
1899         FT_UINT16, BASE_HEX, NULL, 0x00,
1900         NULL, HFILL }
1901     },
1902     { &hf_cops_pc_src_port,
1903       { "Source IP Port", "cops.pc_src_port",
1904         FT_UINT16, BASE_HEX, NULL, 0x00,
1905         NULL, HFILL }
1906     },
1907     { &hf_cops_pc_t1_value,
1908       { "Timer T1 Value (sec)", "cops.pc_t1_value",
1909         FT_UINT16, BASE_HEX, NULL, 0x00,
1910         NULL, HFILL }
1911     },
1912     { &hf_cops_pc_t7_value,
1913       { "Timer T7 Value (sec)", "cops.pc_t7_value",
1914         FT_UINT16, BASE_HEX, NULL, 0x00,
1915         NULL, HFILL }
1916     },
1917     { &hf_cops_pc_t8_value,
1918       { "Timer T8 Value (sec)", "cops.pc_t8_value",
1919         FT_UINT16, BASE_HEX, NULL, 0x00,
1920         NULL, HFILL }
1921     },
1922     { &hf_cops_pc_transaction_id,
1923       { "Transaction Identifier", "cops.pc_transaction_id",
1924         FT_UINT16, BASE_HEX, NULL, 0x00,
1925         NULL, HFILL }
1926     },
1927     { &hf_cops_pc_cmts_ip,
1928       { "CMTS IP Address", "cops.pc_cmts_ip",
1929         FT_IPv4, BASE_NONE, NULL, 0x00,
1930         NULL, HFILL }
1931     },
1932     { &hf_cops_pc_prks_ip,
1933       { "PRKS IP Address", "cops.pc_prks_ip",
1934         FT_IPv4, BASE_NONE, NULL, 0x00,
1935         NULL, HFILL }
1936     },
1937     { &hf_cops_pc_srks_ip,
1938       { "SRKS IP Address", "cops.pc_srks_ip",
1939         FT_IPv4, BASE_NONE, NULL, 0x00,
1940         NULL, HFILL }
1941     },
1942     { &hf_cops_pc_dfcdc_ip,
1943       { "DF IP Address CDC", "cops.pc_dfcdc_ip",
1944         FT_IPv4, BASE_NONE, NULL, 0x00,
1945         NULL, HFILL }
1946     },
1947     { &hf_cops_pc_dfccc_ip,
1948       { "DF IP Address CCC", "cops.pc_dfccc_ip",
1949         FT_IPv4, BASE_NONE, NULL, 0x00,
1950         NULL, HFILL }
1951     },
1952     { &hf_cops_pc_dfcdc_ip_port,
1953       { "DF IP Port CDC", "cops.pc_dfcdc_ip_port",
1954         FT_UINT16, BASE_HEX, NULL, 0x00,
1955         NULL, HFILL }
1956     },
1957     { &hf_cops_pc_dfccc_ip_port,
1958       { "DF IP Port CCC", "cops.pc_dfccc_ip_port",
1959         FT_UINT16, BASE_HEX, NULL, 0x00,
1960         NULL, HFILL }
1961     },
1962     { &hf_cops_pc_dfccc_id,
1963       { "CCC ID", "cops.pc_dfccc_id",
1964         FT_UINT32, BASE_DEC, NULL, 0x00,
1965         NULL, HFILL }
1966     },
1967     { &hf_cops_pc_activity_count,
1968       { "Count", "cops.pc_activity_count",
1969         FT_UINT32, BASE_HEX, NULL, 0x00,
1970         NULL, HFILL }
1971     },
1972     { &hf_cops_pc_dest_ip,
1973       { "Destination IP Address", "cops.pc_dest_ip",
1974         FT_IPv4, BASE_NONE, NULL, 0x00,
1975         NULL, HFILL }
1976     },
1977     { &hf_cops_pc_gate_id,
1978       { "Gate Identifier", "cops.pc_gate_id",
1979         FT_UINT32, BASE_HEX, NULL, 0x00,
1980         NULL, HFILL }
1981     },
1982     { &hf_cops_pc_max_packet_size,
1983       { "Maximum Packet Size", "cops.pc_max_packet_size",
1984         FT_UINT32, BASE_HEX, NULL, 0x00,
1985         NULL, HFILL }
1986     },
1987     { &hf_cops_pc_min_policed_unit,
1988       { "Minimum Policed Unit", "cops.pc_min_policed_unit",
1989         FT_UINT32, BASE_HEX, NULL, 0x00,
1990         NULL, HFILL }
1991     },
1992     { &hf_cops_pc_peak_data_rate,
1993       { "Peak Data Rate", "cops.pc_peak_data_rate",
1994         FT_FLOAT, BASE_NONE, NULL, 0x00,
1995         NULL, HFILL }
1996     },
1997     { &hf_cops_pc_spec_rate,
1998       { "Rate", "cops.pc_spec_rate",
1999         FT_FLOAT, BASE_NONE, NULL, 0x00,
2000         NULL, HFILL }
2001     },
2002     { &hf_cops_pc_remote_gate_id,
2003       { "Remote Gate ID", "cops.pc_remote_gate_id",
2004         FT_UINT32, BASE_HEX, NULL, 0x00,
2005         NULL, HFILL }
2006     },
2007     { &hf_cops_pc_reserved,
2008       { "Reserved", "cops.pc_reserved",
2009         FT_UINT32, BASE_HEX, NULL, 0x00,
2010         NULL, HFILL }
2011     },
2012     { &hf_cops_pc_key,
2013       { "Security Key", "cops.pc_key",
2014         FT_UINT32, BASE_HEX, NULL, 0x00,
2015         NULL, HFILL }
2016     },
2017     { &hf_cops_pc_slack_term,
2018       { "Slack Term", "cops.pc_slack_term",
2019         FT_UINT32, BASE_HEX, NULL, 0x00,
2020         NULL, HFILL }
2021     },
2022     { &hf_cops_pc_src_ip,
2023       { "Source IP Address", "cops.pc_src_ip",
2024         FT_IPv4, BASE_NONE, NULL, 0x00,
2025         NULL, HFILL }
2026     },
2027     { &hf_cops_pc_subscriber_id_ipv4,
2028       { "Subscriber Identifier (IPv4)", "cops.pc_subscriber_id4",
2029         FT_IPv4, BASE_NONE, NULL, 0x00,
2030         NULL, HFILL }
2031     },
2032     { &hf_cops_pc_subscriber_id_ipv6,
2033       { "Subscriber Identifier (IPv6)", "cops.pc_subscriber_id6",
2034         FT_IPv6, BASE_NONE, NULL, 0x00,
2035         NULL, HFILL }
2036     },
2037     { &hf_cops_pc_token_bucket_rate,
2038       { "Token Bucket Rate", "cops.pc_token_bucket_rate",
2039         FT_FLOAT, BASE_NONE, NULL, 0x00,
2040         NULL, HFILL }
2041     },
2042     { &hf_cops_pc_token_bucket_size,
2043       { "Token Bucket Size", "cops.pc_token_bucket_size",
2044         FT_FLOAT, BASE_NONE, NULL, 0x00,
2045         NULL, HFILL }
2046     },
2047     { &hf_cops_pc_bcid,
2048       { "Billing Correlation ID", "cops.pc_bcid",
2049         FT_UINT32, BASE_HEX, NULL, 0x00,
2050         NULL, HFILL }
2051     },
2052     { &hf_cops_pc_bcid_ts,
2053       { "BDID Timestamp", "cops.pc_bcid_ts",
2054         FT_UINT32, BASE_HEX, NULL, 0x00,
2055         "BCID Timestamp", HFILL }
2056     },
2057     { &hf_cops_pc_bcid_ev,
2058       { "BDID Event Counter", "cops.pc_bcid_ev",
2059         FT_UINT32, BASE_HEX, NULL, 0x00,
2060         "BCID Event Counter", HFILL }
2061     },
2062
2063     { &hf_cops_pcmm_amid_app_type,
2064             { "AMID Application Type", "cops.pc_mm_amid_application_type",
2065             FT_UINT32, BASE_DEC, NULL, 0,
2066             "PacketCable Multimedia AMID Application Type", HFILL }
2067     },
2068     { &hf_cops_pcmm_amid_am_tag,
2069             { "AMID Application Manager Tag", "cops.pc_mm_amid_am_tag",
2070             FT_UINT32, BASE_DEC, NULL, 0,
2071             "PacketCable Multimedia AMID Application Manager Tag", HFILL }
2072     },
2073
2074     { &hf_cops_pcmm_gate_spec_flags,
2075             { "Flags", "cops.pc_mm_gs_flags",
2076             FT_UINT8, BASE_HEX, NULL, 0,
2077             "PacketCable Multimedia GateSpec Flags", HFILL }
2078     },
2079     { &hf_cops_pcmm_gate_spec_dscp_tos_field,
2080             { "DSCP/TOS Field",           "cops.pc_mm_gs_dscp",
2081             FT_UINT8, BASE_HEX, NULL, 0,
2082             "PacketCable Multimedia GateSpec DSCP/TOS Field", HFILL }
2083     },
2084     { &hf_cops_pcmm_gate_spec_dscp_tos_mask,
2085             { "DSCP/TOS Mask",           "cops.pc_mm_gs_dscp_mask",
2086             FT_UINT8, BASE_HEX, NULL, 0,
2087             "PacketCable Multimedia GateSpec DSCP/TOS Mask", HFILL }
2088     },
2089     { &hf_cops_pcmm_gate_spec_session_class_id,
2090             { "SessionClassID", "cops.pc_mm_gs_scid",
2091             FT_UINT8, BASE_DEC, NULL, 0,
2092             "PacketCable Multimedia GateSpec SessionClassID", HFILL }
2093     },
2094     { &hf_cops_pcmm_gate_spec_session_class_id_priority,
2095             { "SessionClassID Priority", "cops.pc_mm_gs_scid_prio",
2096             FT_UINT8, BASE_DEC, NULL, 0x07,
2097             "PacketCable Multimedia GateSpec SessionClassID Priority", HFILL }
2098     },
2099     { &hf_cops_pcmm_gate_spec_session_class_id_preemption,
2100             { "SessionClassID Preemption", "cops.pc_mm_gs_scid_preempt",
2101             FT_UINT8, BASE_DEC, NULL, 0x08,
2102             "PacketCable Multimedia GateSpec SessionClassID Preemption", HFILL }
2103     },
2104     { &hf_cops_pcmm_gate_spec_session_class_id_configurable,
2105             { "SessionClassID Configurable", "cops.pc_mm_gs_scid_conf",
2106             FT_UINT8, BASE_DEC, NULL, 0xf0,
2107             "PacketCable Multimedia GateSpec SessionClassID Configurable", HFILL }
2108     },
2109     { &hf_cops_pcmm_gate_spec_timer_t1,
2110             { "Timer T1", "cops.pc_mm_gs_timer_t1",
2111             FT_UINT16, BASE_DEC, NULL, 0,
2112             "PacketCable Multimedia GateSpec Timer T1", HFILL }
2113     },
2114     { &hf_cops_pcmm_gate_spec_timer_t2,
2115             { "Timer T2", "cops.pc_mm_gs_timer_t2",
2116             FT_UINT16, BASE_DEC, NULL, 0,
2117             "PacketCable Multimedia GateSpec Timer T2", HFILL }
2118     },
2119     { &hf_cops_pcmm_gate_spec_timer_t3,
2120             { "Timer T3", "cops.pc_mm_gs_timer_t3",
2121             FT_UINT16, BASE_DEC, NULL, 0,
2122             "PacketCable Multimedia GateSpec Timer T3", HFILL }
2123     },
2124     { &hf_cops_pcmm_gate_spec_timer_t4,
2125             { "Timer T4", "cops.pc_mm_gs_timer_t4",
2126             FT_UINT16, BASE_DEC, NULL, 0,
2127             "PacketCable Multimedia GateSpec Timer T4", HFILL }
2128     },
2129
2130     { &hf_cops_pcmm_classifier_protocol_id,
2131             { "Protocol ID", "cops.pc_mm_classifier_proto_id",
2132             FT_UINT16, BASE_HEX, NULL, 0,
2133             "PacketCable Multimedia Classifier Protocol ID", HFILL }
2134     },
2135     { &hf_cops_pcmm_classifier_dscp_tos_field,
2136             { "DSCP/TOS Field", "cops.pc_mm_classifier_dscp",
2137             FT_UINT8, BASE_HEX, NULL, 0,
2138             "PacketCable Multimedia Classifier DSCP/TOS Field", HFILL }
2139     },
2140     { &hf_cops_pcmm_classifier_dscp_tos_mask,
2141             { "DSCP/TOS Mask", "cops.pc_mm_classifier_dscp_mask",
2142             FT_UINT8, BASE_HEX, NULL, 0,
2143             "PacketCable Multimedia Classifier DSCP/TOS Mask", HFILL }
2144     },
2145     { &hf_cops_pcmm_classifier_src_addr,
2146             { "Source address", "cops.pc_mm_classifier_src_addr",
2147             FT_IPv4, BASE_NONE, NULL, 0,
2148             "PacketCable Multimedia Classifier Source IP Address", HFILL }
2149     },
2150     { &hf_cops_pcmm_classifier_src_mask,
2151             { "Source mask", "cops.pc_mm_classifier_src_mask",
2152             FT_IPv4, BASE_NONE, NULL, 0,
2153             "PacketCable Multimedia Classifier Source Mask", HFILL }
2154     },
2155     { &hf_cops_pcmm_classifier_dst_addr,
2156             { "Destination address", "cops.pc_mm_classifier_dst_addr",
2157             FT_IPv4, BASE_NONE, NULL, 0,
2158             "PacketCable Multimedia Classifier Destination IP Address", HFILL }
2159     },
2160     { &hf_cops_pcmm_classifier_dst_mask,
2161             { "Destination mask", "cops.pc_mm_classifier_dst_mask",
2162             FT_IPv4, BASE_NONE, NULL, 0,
2163             "PacketCable Multimedia Classifier Destination Mask", HFILL }
2164     },
2165     { &hf_cops_pcmm_classifier_src_port,
2166             { "Source Port", "cops.pc_mm_classifier_src_port",
2167             FT_UINT16, BASE_DEC, NULL, 0,
2168             "PacketCable Multimedia Classifier Source Port", HFILL }
2169     },
2170     { &hf_cops_pcmm_classifier_src_port_end,
2171             { "Source Port End", "cops.pc_mm_classifier_src_port_end",
2172             FT_UINT16, BASE_DEC, NULL, 0,
2173             "PacketCable Multimedia Classifier Source Port End", HFILL }
2174     },
2175     { &hf_cops_pcmm_classifier_dst_port,
2176             { "Destination Port", "cops.pc_mm_classifier_dst_port",
2177             FT_UINT16, BASE_DEC, NULL, 0,
2178             "PacketCable Multimedia Classifier Source Port", HFILL }
2179     },
2180     { &hf_cops_pcmm_classifier_dst_port_end,
2181             { "Destination Port End", "cops.pc_mm_classifier_dst_port_end",
2182             FT_UINT16, BASE_DEC, NULL, 0,
2183             "PacketCable Multimedia Classifier Source Port End", HFILL }
2184     },
2185     { &hf_cops_pcmm_classifier_priority,
2186             { "Priority", "cops.pc_mm_classifier_priority",
2187             FT_UINT8, BASE_HEX, NULL, 0,
2188             "PacketCable Multimedia Classifier Priority", HFILL }
2189     },
2190     { &hf_cops_pcmm_classifier_classifier_id,
2191             { "Classifier Id", "cops.pc_mm_classifier_id",
2192             FT_UINT16, BASE_HEX, NULL, 0,
2193             "PacketCable Multimedia Classifier ID", HFILL }
2194     },
2195     { &hf_cops_pcmm_classifier_activation_state,
2196             { "Activation State", "cops.pc_mm_classifier_activation_state",
2197             FT_UINT8, BASE_HEX, pcmm_activation_state_vals, 0,
2198             "PacketCable Multimedia Classifier Activation State", HFILL }
2199     },
2200     { &hf_cops_pcmm_classifier_action,
2201             { "Action", "cops.pc_mm_classifier_action",
2202             FT_UINT8, BASE_HEX, pcmm_action_vals, 0,
2203             "PacketCable Multimedia Classifier Action", HFILL }
2204     },
2205     { &hf_cops_pcmm_classifier_flags,
2206             { "Flags", "cops.pc_mm_classifier_flags",
2207             FT_UINT8, BASE_HEX, NULL, 0,
2208             "PacketCable Multimedia Classifier Flags", HFILL }
2209     },
2210     { &hf_cops_pcmm_classifier_tc_low,
2211             { "tc-low", "cops.pc_mm_classifier_tc_low",
2212             FT_UINT8, BASE_HEX, NULL, 0,
2213             "PacketCable Multimedia Classifier tc-low", HFILL }
2214     },
2215     { &hf_cops_pcmm_classifier_tc_high,
2216             { "tc-high", "cops.pc_mm_classifier_tc_high",
2217             FT_UINT8, BASE_HEX, NULL, 0,
2218             "PacketCable Multimedia Classifier tc-high", HFILL }
2219     },
2220     { &hf_cops_pcmm_classifier_tc_mask,
2221             { "tc-mask", "cops.pc_mm_classifier_tc_mask",
2222             FT_UINT8, BASE_HEX, NULL, 0,
2223             "PacketCable Multimedia Classifier tc-mask", HFILL }
2224     },
2225     { &hf_cops_pcmm_classifier_flow_label,
2226             { "Flow Label", "cops.pc_mm_classifier_flow_label",
2227             FT_UINT32, BASE_HEX, NULL, 0,
2228             "PacketCable Multimedia Classifier Flow Label", HFILL }
2229     },
2230     { &hf_cops_pcmm_classifier_next_header_type,
2231             { "Next Header Type", "cops.pc_mm_classifier_next_header_type",
2232             FT_UINT16, BASE_HEX, NULL, 0,
2233             "PacketCable Multimedia Classifier Next Header Type", HFILL }
2234     },
2235     { &hf_cops_pcmm_classifier_source_prefix_length,
2236             { "Source Prefix Length", "cops.pc_mm_classifier_source_prefix_length",
2237             FT_UINT8, BASE_HEX, NULL, 0,
2238             "PacketCable Multimedia Classifier Source Prefix Length", HFILL }
2239     },
2240     { &hf_cops_pcmm_classifier_destination_prefix_length,
2241             { "Destination Prefix Length", "cops.pc_mm_classifier_destination_prefix_length",
2242             FT_UINT8, BASE_HEX, NULL, 0,
2243             "PacketCable Multimedia Classifier Destination Prefix Length", HFILL }
2244     },
2245     { &hf_cops_pcmm_classifier_src_addr_v6,
2246             { "IPv6 Source Address", "cops.pc_mm_classifier_src_addr_v6",
2247             FT_IPv6, BASE_NONE, NULL, 0,
2248             "PacketCable Multimedia Classifier IPv6 Source Address", HFILL }
2249     },
2250     { &hf_cops_pcmm_classifier_dst_addr_v6,
2251             { "IPv6 Destination Address", "cops.pc_mm_classifier_dst_addr_v6",
2252             FT_IPv6, BASE_NONE, NULL, 0,
2253             "PacketCable Multimedia Classifier IPv6 Destination Address", HFILL }
2254     },
2255
2256     { &hf_cops_pcmm_flow_spec_envelope,
2257             { "Envelope", "cops.pc_mm_fs_envelope",
2258             FT_UINT8, BASE_DEC, NULL, 0,
2259             "PacketCable Multimedia Flow Spec Envelope", HFILL }
2260     },
2261     { &hf_cops_pcmm_flow_spec_service_number,
2262             { "Service Number", "cops.pc_mm_fs_svc_num",
2263             FT_UINT8, BASE_DEC, pcmm_flow_spec_service_vals, 0,
2264             "PacketCable Multimedia Flow Spec Service Number", HFILL }
2265     },
2266
2267     { &hf_cops_pcmm_docsis_scn,
2268             { "Service Class Name", "cops.pc_mm_docsis_scn",
2269             FT_STRINGZ, BASE_NONE, NULL, 0,
2270             "PacketCable Multimedia DOCSIS Service Class Name", HFILL }
2271     },
2272
2273     { &hf_cops_pcmm_envelope,
2274             { "Envelope", "cops.pc_mm_envelope",
2275             FT_UINT8, BASE_DEC, NULL, 0,
2276             "PacketCable Multimedia Envelope", HFILL }
2277     },
2278
2279     { &hf_cops_pcmm_traffic_priority,
2280             { "Traffic Priority", "cops.pc_mm_tp",
2281             FT_UINT8, BASE_DEC, NULL, 0,
2282             "PacketCable Multimedia Committed Envelope Traffic Priority", HFILL }
2283     },
2284     { &hf_cops_pcmm_request_transmission_policy,
2285             { "Request Transmission Policy", "cops.pc_mm_rtp",
2286             FT_UINT32, BASE_HEX, NULL, 0,
2287             "PacketCable Multimedia Committed Envelope Traffic Priority", HFILL }
2288     },
2289     { &hf_cops_pcmm_max_sustained_traffic_rate,
2290             { "Maximum Sustained Traffic Rate", "cops.pc_mm_mstr",
2291             FT_UINT32, BASE_DEC, NULL, 0,
2292             "PacketCable Multimedia Committed Envelope Maximum Sustained Traffic Rate", HFILL }
2293     },
2294     { &hf_cops_pcmm_max_traffic_burst,
2295             { "Maximum Traffic Burst", "cops.pc_mm_mtb",
2296             FT_UINT32, BASE_DEC, NULL, 0,
2297             "PacketCable Multimedia Committed Envelope Maximum Traffic Burst", HFILL }
2298     },
2299     { &hf_cops_pcmm_min_reserved_traffic_rate,
2300             { "Minimum Reserved Traffic Rate", "cops.pc_mm_mrtr",
2301             FT_UINT32, BASE_DEC, NULL, 0,
2302             "PacketCable Multimedia Committed Envelope Minimum Reserved Traffic Rate", HFILL }
2303     },
2304     { &hf_cops_pcmm_ass_min_rtr_packet_size,
2305             { "Assumed Minimum Reserved Traffic Rate Packet Size", "cops.pc_mm_amrtrps",
2306             FT_UINT16, BASE_DEC, NULL, 0,
2307             "PacketCable Multimedia Committed Envelope Assumed Minimum Reserved Traffic Rate Packet Size", HFILL }
2308     },
2309     { &hf_cops_pcmm_max_concat_burst,
2310                 { "Maximum Concatenated Burst", "cops.pc_mm_mcburst",
2311                 FT_UINT16, BASE_DEC, NULL, 0,
2312                 "PacketCable Multimedia Committed Envelope Maximum Concatenated Burst", HFILL }
2313     },
2314     { &hf_cops_pcmm_req_att_mask,
2315                 { "Required Attribute Mask", "cops.pc_mm_ramask",
2316                 FT_UINT16, BASE_DEC, NULL, 0,
2317                 "PacketCable Multimedia Committed Envelope Required Attribute Mask", HFILL }
2318     },
2319     { &hf_cops_pcmm_forbid_att_mask,
2320                 { "Forbidden Attribute Mask", "cops.pc_mm_famask",
2321                 FT_UINT16, BASE_DEC, NULL, 0,
2322                 "PacketCable Multimedia Committed Envelope Forbidden Attribute Mask", HFILL }
2323     },
2324     { &hf_cops_pcmm_att_aggr_rule_mask,
2325                 { "Attribute Aggregation Rule Mask", "cops.pc_mm_aarmask",
2326                 FT_UINT16, BASE_DEC, NULL, 0,
2327                 "PacketCable Multimedia Committed Envelope Attribute Aggregation Rule Mask", HFILL }
2328     },
2329
2330     { &hf_cops_pcmm_nominal_polling_interval,
2331             { "Nominal Polling Interval", "cops.pc_mm_npi",
2332             FT_UINT32, BASE_DEC, NULL, 0,
2333             "PacketCable Multimedia Nominal Polling Interval", HFILL }
2334     },
2335
2336     { &hf_cops_pcmm_tolerated_poll_jitter,
2337             { "Tolerated Poll Jitter", "cops.pc_mm_tpj",
2338             FT_UINT32, BASE_DEC, NULL, 0,
2339             "PacketCable Multimedia Tolerated Poll Jitter", HFILL }
2340     },
2341
2342     { &hf_cops_pcmm_unsolicited_grant_size,
2343             { "Unsolicited Grant Size", "cops.pc_mm_ugs",
2344             FT_UINT16, BASE_DEC, NULL, 0,
2345             "PacketCable Multimedia Unsolicited Grant Size", HFILL }
2346     },
2347     { &hf_cops_pcmm_grants_per_interval,
2348             { "Grants Per Interval", "cops.pc_mm_gpi",
2349             FT_UINT8, BASE_DEC, NULL, 0,
2350             "PacketCable Multimedia Grants Per Interval", HFILL }
2351     },
2352     { &hf_cops_pcmm_nominal_grant_interval,
2353             { "Nominal Grant Interval", "cops.pc_mm_ngi",
2354             FT_UINT32, BASE_DEC, NULL, 0,
2355             "PacketCable Multimedia Nominal Grant Interval", HFILL }
2356     },
2357     { &hf_cops_pcmm_tolerated_grant_jitter,
2358             { "Tolerated Grant Jitter", "cops.pc_mm_tgj",
2359             FT_UINT32, BASE_DEC, NULL, 0,
2360             "PacketCable Multimedia Tolerated Grant Jitter", HFILL }
2361     },
2362
2363     { &hf_cops_pcmm_down_resequencing,
2364                 { "Downstream Resequencing", "cops.pc_mm_downres",
2365                 FT_UINT32, BASE_DEC, NULL, 0,
2366                 "PacketCable Multimedia Downstream Resequencing", HFILL }
2367         },
2368
2369         { &hf_cops_pcmm_down_peak_traffic_rate,
2370                 { "Downstream Peak Traffic Rate", "cops.pc_mm_downpeak",
2371                 FT_UINT32, BASE_DEC, NULL, 0,
2372                 "PacketCable Multimedia Downstream Peak Traffic Rate", HFILL }
2373         },
2374
2375     { &hf_cops_pcmm_max_downstream_latency,
2376             { "Maximum Downstream Latency", "cops.pc_mm_mdl",
2377             FT_UINT32, BASE_DEC, NULL, 0,
2378             "PacketCable Multimedia Maximum Downstream Latency", HFILL }
2379     },
2380
2381     { &hf_cops_pcmm_volume_based_usage_limit,
2382             { "Usage Limit", "cops.pc_mm_vbul_ul",
2383             FT_UINT64, BASE_DEC, NULL, 0,
2384             "PacketCable Multimedia Volume-Based Usage Limit", HFILL }
2385     },
2386
2387     { &hf_cops_pcmm_time_based_usage_limit,
2388             { "Usage Limit", "cops.pc_mm_tbul_ul",
2389             FT_UINT32, BASE_DEC, NULL, 0,
2390             "PacketCable Multimedia Time-Based Usage Limit", HFILL }
2391     },
2392
2393     { &hf_cops_pcmm_gate_time_info,
2394             { "Gate Time Info", "cops.pc_mm_gti",
2395             FT_UINT32, BASE_DEC, NULL, 0,
2396             "PacketCable Multimedia Gate Time Info", HFILL }
2397     },
2398
2399     { &hf_cops_pcmm_gate_usage_info,
2400             { "Gate Usage Info", "cops.pc_mm_gui",
2401             FT_UINT64, BASE_DEC, NULL, 0,
2402             "PacketCable Multimedia Gate Usage Info", HFILL }
2403     },
2404
2405     { &hf_cops_pcmm_packetcable_error_code,
2406             { "Error-Code", "cops.pc_mm_error_ec",
2407             FT_UINT16, BASE_DEC, NULL, 0,
2408             "PacketCable Multimedia PacketCable-Error Error-Code", HFILL }
2409     },
2410     { &hf_cops_pcmm_packetcable_error_subcode,
2411             { "Error-code", "cops.pc_mm_error_esc",
2412             FT_UINT16, BASE_HEX, NULL, 0,
2413             "PacketCable Multimedia PacketCable-Error Error Sub-code", HFILL }
2414     },
2415
2416     { &hf_cops_pcmm_packetcable_gate_state,
2417             { "State", "cops.pc_mm_gs_state",
2418             FT_UINT16, BASE_DEC, NULL, 0,
2419             "PacketCable Multimedia Gate State", HFILL }
2420     },
2421     { &hf_cops_pcmm_packetcable_gate_state_reason,
2422             { "Reason", "cops.pc_mm_gs_reason",
2423             FT_UINT16, BASE_HEX, NULL, 0,
2424             "PacketCable Multimedia Gate State Reason", HFILL }
2425     },
2426     { &hf_cops_pcmm_packetcable_version_info_major,
2427             { "Major Version Number", "cops.pc_mm_vi_major",
2428             FT_UINT16, BASE_DEC, NULL, 0,
2429             "PacketCable Multimedia Major Version Number", HFILL }
2430     },
2431     { &hf_cops_pcmm_packetcable_version_info_minor,
2432             { "Minor Version Number", "cops.pc_mm_vi_minor",
2433             FT_UINT16, BASE_DEC, NULL, 0,
2434             "PacketCable Multimedia Minor Version Number", HFILL }
2435     },
2436
2437     { &hf_cops_pcmm_psid,
2438             { "PSID", "cops.pc_mm_psid",
2439             FT_UINT32, BASE_DEC, NULL, 0,
2440             "PacketCable Multimedia PSID", HFILL }
2441     },
2442
2443     { &hf_cops_pcmm_synch_options_report_type,
2444             { "Report Type", "cops.pc_mm_synch_options_report_type",
2445             FT_UINT8, BASE_DEC, pcmm_report_type_vals, 0,
2446             "PacketCable Multimedia Synch Options Report Type", HFILL }
2447     },
2448     { &hf_cops_pcmm_synch_options_synch_type,
2449             { "Synch Type", "cops.pc_mm_synch_options_synch_type",
2450             FT_UINT8, BASE_DEC, pcmm_synch_type_vals, 0,
2451             "PacketCable Multimedia Synch Options Synch Type", HFILL }
2452     },
2453
2454     { &hf_cops_pcmm_msg_receipt_key,
2455             { "Msg Receipt Key", "cops.pc_mm_msg_receipt_key",
2456             FT_UINT32, BASE_HEX, NULL, 0,
2457             "PacketCable Multimedia Msg Receipt Key", HFILL }
2458     },
2459
2460     { &hf_cops_pcmm_userid,
2461             { "UserID", "cops.pc_mm_userid",
2462             FT_STRING, BASE_NONE, NULL, 0,
2463             "PacketCable Multimedia UserID", HFILL }
2464     },
2465
2466     { &hf_cops_pcmm_sharedresourceid,
2467             { "SharedResourceID", "cops.pc_mm_sharedresourceid",
2468             FT_UINT32, BASE_HEX, NULL, 0,
2469             "PacketCable Multimedia SharedResourceID", HFILL }
2470     },
2471
2472     /* End of addition for PacketCable */
2473
2474   };
2475
2476   /* Setup protocol subtree array */
2477   static gint *ett[] = {
2478     &ett_cops,
2479     &ett_cops_ver_flags,
2480     &ett_cops_obj,
2481     &ett_cops_pr_obj,
2482     &ett_cops_obj_data,
2483     &ett_cops_r_type_flags,
2484     &ett_cops_itf,
2485     &ett_cops_reason,
2486     &ett_cops_decision,
2487     &ett_cops_error,
2488     &ett_cops_clientsi,
2489     &ett_cops_asn1,
2490     &ett_cops_gperror,
2491     &ett_cops_cperror,
2492     &ett_cops_pdp,
2493     &ett_cops_subtree,
2494     &ett_docsis_request_transmission_policy,
2495   };
2496
2497   module_t* cops_module;
2498
2499   /* Register the protocol name and description */
2500   proto_cops = proto_register_protocol("Common Open Policy Service",
2501       "COPS", "cops");
2502
2503   /* Required function calls to register the header fields and subtrees used */
2504   proto_register_field_array(proto_cops, hf, array_length(hf));
2505   proto_register_subtree_array(ett, array_length(ett));
2506
2507   /* Make dissector findable by name */
2508   register_dissector("cops", dissect_cops, proto_cops);
2509
2510   /* Register our configuration options for cops */
2511   cops_module = prefs_register_protocol(proto_cops, proto_reg_handoff_cops);
2512   prefs_register_uint_preference(cops_module,"tcp.cops_port",
2513                                  "COPS TCP Port",
2514                                  "Set the TCP port for COPS messages",
2515                                  10,&global_cops_tcp_port);
2516   prefs_register_bool_preference(cops_module, "desegment",
2517                                  "Reassemble COPS messages spanning multiple TCP segments",
2518                                  "Whether the COPS dissector should reassemble messages spanning multiple TCP segments."
2519                                  " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2520                                  &cops_desegment);
2521
2522   /* For PacketCable */
2523   prefs_register_bool_preference(cops_module, "packetcable",
2524                                  "Decode for PacketCable clients",
2525                                  "Decode the COPS messages using PacketCable clients. (Select port 2126)",
2526                                  &cops_packetcable);
2527
2528   prefs_register_static_text_preference(cops_module, "info_pibs",
2529       "PIB settings can be changed in the Name Resolution preferences",
2530       "PIB settings can be changed in the Name Resolution preferences");
2531
2532   prefs_register_obsolete_preference(cops_module, "typefrommib");
2533 }
2534
2535 void proto_reg_handoff_cops(void)
2536 {
2537   static gboolean cops_prefs_initialized = FALSE;
2538   static dissector_handle_t cops_handle;
2539   static guint cops_tcp_port;
2540
2541   if (!cops_prefs_initialized) {
2542     cops_handle = find_dissector("cops");
2543     dissector_add_uint("tcp.port", TCP_PORT_PKTCABLE_COPS, cops_handle);
2544     dissector_add_uint("tcp.port", TCP_PORT_PKTCABLE_MM_COPS, cops_handle);
2545     cops_prefs_initialized = TRUE;
2546   } else {
2547     dissector_delete_uint("tcp.port",cops_tcp_port,cops_handle);
2548   }
2549   cops_tcp_port = global_cops_tcp_port;
2550
2551   dissector_add_uint("tcp.port", cops_tcp_port, cops_handle);
2552 }
2553
2554
2555 /* Additions for PacketCable ( Added by Dick Gooris, Lucent Technologies ) */
2556
2557 /* Definitions for print formatting */
2558 /* XXX - Why don't we just use ftenum types here? */
2559 #define   FMT_DEC   0
2560 #define   FMT_HEX   1
2561 #define   FMT_IPv4  2
2562 #define   FMT_IPv6  3
2563 #define   FMT_FLT   4
2564 #define   FMT_STR   5
2565
2566 /* Print the translated information in the display gui in a formatted way
2567  *
2568  * octets = The number of octets to obtain from the buffer
2569  *
2570  * vsp    = If not a NULL pointer, it points to an array with text
2571  *
2572  * mode   = 0 -> print decimal value
2573  *          1 -> print hexadecimal vaue
2574  *          2 -> print value as an IPv4 address
2575  *          3 -> print value as an IPv6 address
2576  *          4 -> print value as an IEEE float
2577  *          5 -> print value as a string
2578  *
2579  * This function in combination with the separate function info_to_cops_subtree() for subtrees.
2580  *
2581  */
2582
2583 static proto_item *
2584 info_to_display(tvbuff_t *tvb, proto_item *stt, int offset, int octets, const char *str, const value_string *vsp, int mode,gint *hf_proto_parameter)
2585 {
2586      proto_item *pi = NULL;
2587      guint8   *codestr;
2588      guint8   code8  = 0;
2589      guint16  code16 = 0;
2590      guint32  codeipv4 = 0;
2591      guint32  code32 = 0;
2592      guint64  code64 = 0;
2593      float    codefl = 0.0f;
2594
2595      /* Special section for printing strings */
2596          if (mode==FMT_STR) {
2597                  codestr = tvb_get_ephemeral_string(tvb, offset, octets);
2598                  pi = proto_tree_add_string_format(stt, *hf_proto_parameter, tvb,
2599                  offset, octets, codestr, "%-28s : %s", str, codestr);
2600                  return pi;
2601          }
2602
2603      /* Print information elements in the specified way */
2604      switch (octets) {
2605
2606      case 1:
2607              /* Get the octet */
2608              code8 = tvb_get_guint8( tvb, offset );
2609              if (vsp == NULL) {
2610                 /* Hexadecimal format */
2611                 if (mode==FMT_HEX)
2612                    pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb,
2613                        offset, octets, code8,"%-28s : 0x%02x",str,code8);
2614                 else
2615                    /* Print an 8 bits integer */
2616                    pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb,
2617                        offset, octets, code8,"%-28s : %u",str,code8);
2618              } else {
2619                if (mode==FMT_HEX)
2620                   /* Hexadecimal format */
2621                   pi = proto_tree_add_uint_format(
2622                       stt, *hf_proto_parameter,tvb, offset, octets, code8,
2623                       "%-28s : %s (0x%02x)",str,val_to_str(code8, vsp, "Unknown"),code8);
2624                else
2625                   /* String table indexed */
2626                   pi = proto_tree_add_uint_format(
2627                       stt, *hf_proto_parameter,tvb, offset, octets, code8,
2628                       "%-28s : %s (%u)",str,val_to_str(code8, vsp, "Unknown"),code8);
2629              }
2630              break;
2631
2632        case 2:
2633
2634              /* Get the next two octets */
2635              code16 = tvb_get_ntohs(tvb,offset);
2636              if (vsp == NULL) {
2637                 /* Hexadecimal format */
2638                 if (mode==FMT_HEX)
2639                    pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb,
2640                        offset, octets, code16,"%-28s : 0x%04x",str,code16);
2641                 else
2642                    /* Print a 16 bits integer */
2643                    pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb,
2644                        offset, octets, code16,"%-28s : %u",str,code16);
2645              }  else {
2646                 if (mode==FMT_HEX)
2647                    /* Hexadecimal format */
2648                    pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb,
2649                        offset, octets, code16,"%-28s : %s (0x%04x)", str,
2650                        val_to_str(code16, vsp, "Unknown (0x%04x)"),code16);
2651                 else
2652                    /* Print a 16 bits integer */
2653                    pi = proto_tree_add_uint_format(
2654                        stt, *hf_proto_parameter,tvb, offset, octets, code16,
2655                        "%-28s : %s (%u)",str,val_to_str(code16, vsp, "Unknown (0x%04x)"),code16);
2656              }
2657              break;
2658
2659         case 4:
2660
2661              /* Get the next four octets */
2662              switch (mode) {
2663                case FMT_FLT:  codefl  = tvb_get_ntohieee_float(tvb,offset);
2664                               break;
2665                case FMT_IPv4: codeipv4 = tvb_get_ipv4(tvb, offset);
2666                               break;
2667                default:       code32  = tvb_get_ntohl(tvb,offset);
2668              }
2669
2670              if (vsp == NULL) {
2671                 /* Hexadecimal format */
2672                 if (mode==FMT_HEX) {
2673                    pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb,
2674                        offset, octets, code32,"%-28s : 0x%08x",str,code32);
2675                    break;
2676                 }
2677                 /* Ip address format*/
2678                 if (mode==FMT_IPv4) {
2679                    pi = proto_tree_add_ipv4(stt, *hf_proto_parameter,tvb, offset, octets, codeipv4);
2680                    break;
2681                 }
2682                 /* Ieee float format */
2683                 if (mode==FMT_FLT) {
2684                    pi = proto_tree_add_float_format(stt, *hf_proto_parameter,tvb, offset, octets,
2685                        codefl,"%-28s : %.10g",str,codefl);
2686                    break;
2687                 }
2688                 /* Print a 32 bits integer */
2689                 pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb, offset, octets,
2690                     code32,"%-28s : %u",str,code32);
2691              } else {
2692                 /* Hexadecimal format */
2693                 if (mode==FMT_HEX)
2694                    pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb, offset, octets,
2695                            code32,"%-28s : %s (0x%08x)",str,val_to_str(code32, vsp, "Unknown"),code32);
2696                 else
2697                    /* String table indexed */
2698                    pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,tvb, offset, octets,
2699                        code32,"%-28s : %s (%u)",str,val_to_str(code32, vsp, "Unknown"),code32);
2700              }
2701              break;
2702
2703         /* In case of more than 4 octets.... */
2704         default:
2705
2706              if (mode==FMT_HEX) {
2707                 pi = proto_tree_add_item(stt, *hf_proto_parameter,
2708                    tvb, offset, octets, ENC_NA);
2709              } else if (mode==FMT_IPv6 && octets==16) {
2710                 pi = proto_tree_add_item(stt, *hf_proto_parameter, tvb, offset, octets,
2711                    ENC_NA);
2712              } else if (mode==FMT_DEC && octets==8) {
2713                 code64 = tvb_get_ntoh64(tvb, offset);
2714                 pi = proto_tree_add_uint64_format(stt, *hf_proto_parameter, tvb, offset, octets,
2715                    code64, "%-28s : %" G_GINT64_MODIFIER "u", str, code64);
2716              } else {
2717                 pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,
2718                    tvb, offset, octets, code32,"%s",str);
2719              }
2720              break;
2721
2722      }
2723      return pi;
2724 }
2725
2726 /* Print the subtree information for cops */
2727 static proto_tree *
2728 info_to_cops_subtree(tvbuff_t *tvb, proto_tree *st, int n, int offset, const char *str) {
2729      proto_item *tv;
2730
2731      tv  = proto_tree_add_none_format( st, hf_cops_subtree, tvb, offset, n, "%s", str);
2732      return( proto_item_add_subtree( tv, ett_cops_subtree ) );
2733 }
2734
2735 /* Cops - Section : D-QoS Transaction ID */
2736 static void
2737 cops_transaction_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *st, guint8 op_code, guint n, guint32 offset) {
2738
2739      proto_tree *stt;
2740      guint16  code16;
2741      char info[50];
2742
2743      /* Create a subtree */
2744      stt = info_to_cops_subtree(tvb,st,n,offset,"D-QoS Transaction ID");
2745      offset += 4;
2746
2747      /* Transaction Identifier */
2748      info_to_display(tvb,stt,offset,2,"D-QoS Transaction Identifier", NULL,FMT_DEC,&hf_cops_pc_transaction_id);
2749      offset +=2;
2750
2751      /* Gate Command Type */
2752      code16 = tvb_get_ntohs(tvb,offset);
2753      proto_tree_add_uint_format(stt, hf_cops_pc_gate_command_type,tvb, offset, 2,
2754             code16,"%-28s : %s (%u)", "Gate Command Type",
2755             val_to_str(code16,table_cops_dqos_transaction_id, "Unknown (0x%04x)"),code16);
2756
2757      /* Write the right data into the 'info field' on the Gui */
2758      g_snprintf(info,sizeof(info),"COPS %-20s - %s",val_to_str(op_code,cops_op_code_vals, "Unknown"),
2759                 val_to_str(code16,table_cops_dqos_transaction_id, "Unknown"));
2760
2761      col_clear(pinfo->cinfo, COL_INFO);
2762      col_add_str(pinfo->cinfo, COL_INFO,info);
2763 }
2764
2765 /* Cops - Section : Subscriber IDv4 */
2766 static void
2767 cops_subscriber_id_v4(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
2768
2769      proto_item *tv;
2770
2771      /* Create a subtree */
2772      tv = info_to_cops_subtree(tvb,st,n,offset,"Subscriber ID (IPv4)");
2773      offset += 4;
2774
2775      /* Subscriber Identifier */
2776      info_to_display(tvb,tv,offset,4,"Subscriber Identifier (IPv4)", NULL,FMT_IPv4,&hf_cops_pc_subscriber_id_ipv4);
2777 }
2778
2779 /* Cops - Section : Subscriber IDv6 */
2780 static void
2781 cops_subscriber_id_v6(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
2782
2783      proto_item *tv;
2784
2785      /* Create a subtree */
2786      tv = info_to_cops_subtree(tvb,st,n,offset,"Subscriber ID (IPv6)");
2787      offset += 4;
2788
2789      /* Subscriber Identifier */
2790      info_to_display(tvb,tv,offset,16,"Subscriber Identifier (IPv6)", NULL,FMT_IPv6,&hf_cops_pc_subscriber_id_ipv6);
2791 }
2792
2793 /* Cops - Section : Gate ID */
2794 static void
2795 cops_gate_id(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
2796
2797      proto_tree *stt;
2798
2799      /* Create a subtree */
2800      stt = info_to_cops_subtree(tvb,st,n,offset,"Gate ID");
2801      offset += 4;
2802
2803      /* Gate Identifier */
2804      info_to_display(tvb,stt,offset,4,"Gate Identifier", NULL,FMT_HEX,&hf_cops_pc_gate_id);
2805 }
2806
2807 /* Cops - Section : Activity Count */
2808 static void
2809 cops_activity_count(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
2810
2811      proto_tree *stt;
2812
2813      /* Create a subtree */
2814      stt = info_to_cops_subtree(tvb,st,n,offset,"Activity Count");
2815      offset += 4;
2816
2817      /* Activity Count */
2818      info_to_display(tvb,stt,offset,4,"Count", NULL,FMT_DEC,&hf_cops_pc_activity_count);
2819 }
2820
2821 /* Cops - Section : Gate Specifications */
2822 static void
2823 cops_gate_specs(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
2824
2825      proto_tree *stt;
2826
2827      /* Create a subtree */
2828      stt = info_to_cops_subtree(tvb,st,n,offset,"Gate Specifications");
2829      offset += 4;
2830
2831      /* Direction */
2832      info_to_display(tvb,stt,offset,1,"Direction",table_cops_direction,FMT_DEC,&hf_cops_pc_direction);
2833      offset += 1;
2834
2835      /* Protocol ID */
2836      info_to_display(tvb,stt,offset,1,"Protocol ID",NULL,FMT_DEC,&hf_cops_pc_protocol_id);
2837      offset += 1;
2838
2839      /* Flags */
2840      info_to_display(tvb,stt,offset,1,"Flags",NULL,FMT_DEC,&hf_cops_pc_gate_spec_flags);
2841      offset += 1;
2842
2843      /* Session Class */
2844      info_to_display(tvb,stt,offset,1,"Session Class",table_cops_session_class,FMT_DEC,&hf_cops_pc_session_class);
2845      offset += 1;
2846
2847      /* Source IP Address */
2848      info_to_display(tvb,stt,offset,4,"Source IP Address",NULL,FMT_IPv4,&hf_cops_pc_src_ip);
2849      offset += 4;
2850
2851      /* Destination IP Address */
2852      info_to_display(tvb,stt,offset,4,"Destination IP Address",NULL,FMT_IPv4,&hf_cops_pc_dest_ip);
2853      offset += 4;
2854
2855      /* Source IP Port */
2856      info_to_display(tvb,stt,offset,2,"Source IP Port",NULL,FMT_DEC,&hf_cops_pc_src_port);
2857      offset += 2;
2858
2859      /* Destination IP Port */
2860      info_to_display(tvb,stt,offset,2,"Destination IP Port",NULL,FMT_DEC,&hf_cops_pc_dest_port);
2861      offset += 2;
2862
2863      /* DiffServ Code Point */
2864      info_to_display(tvb,stt,offset,1,"DS Field (DSCP or TOS)",NULL,FMT_HEX,&hf_cops_pc_ds_field);
2865      offset += 1;
2866
2867      /* 3 octets Not specified */
2868      offset += 3;
2869
2870      /* Timer T1 Value */
2871      info_to_display(tvb,stt,offset,2,"Timer T1 Value (sec)",NULL,FMT_DEC,&hf_cops_pc_t1_value);
2872      offset += 2;
2873
2874      /* Reserved */
2875      info_to_display(tvb,stt,offset,2,"Reserved",NULL,FMT_DEC,&hf_cops_pc_reserved);
2876      offset += 2;
2877
2878      /* Timer T7 Value */
2879      info_to_display(tvb,stt,offset,2,"Timer T7 Value (sec)",NULL,FMT_DEC,&hf_cops_pc_t7_value);
2880      offset += 2;
2881
2882      /* Timer T8 Value */
2883      info_to_display(tvb,stt,offset,2,"Timer T8 Value (sec)",NULL,FMT_DEC,&hf_cops_pc_t8_value);
2884      offset += 2;
2885
2886      /* Token Bucket Rate */
2887      info_to_display(tvb,stt,offset,4,"Token Bucket Rate",NULL,FMT_FLT,&hf_cops_pc_token_bucket_rate);
2888      offset += 4;
2889
2890      /* Token Bucket Size */
2891      info_to_display(tvb,stt,offset,4,"Token Bucket Size",NULL,FMT_FLT,&hf_cops_pc_token_bucket_size);
2892      offset += 4;
2893
2894      /* Peak Data Rate */
2895      info_to_display(tvb,stt,offset,4,"Peak Data Rate",NULL,FMT_FLT,&hf_cops_pc_peak_data_rate);
2896      offset += 4;
2897
2898      /* Minimum Policed Unit */
2899      info_to_display(tvb,stt,offset,4,"Minimum Policed Unit",NULL,FMT_DEC,&hf_cops_pc_min_policed_unit);
2900      offset += 4;
2901
2902      /* Maximum Packet Size */
2903      info_to_display(tvb,stt,offset,4,"Maximum Packet Size",NULL,FMT_DEC,&hf_cops_pc_max_packet_size);
2904      offset += 4;
2905
2906      /* Rate */
2907      info_to_display(tvb,stt,offset,4,"Rate",NULL,FMT_FLT,&hf_cops_pc_spec_rate);
2908      offset += 4;
2909
2910      /* Slack Term */
2911      info_to_display(tvb,stt,offset,4,"Slack Term",NULL,FMT_DEC,&hf_cops_pc_slack_term);
2912 }
2913
2914 /* Cops - Section : Electronic Surveillance Parameters  */
2915 static void
2916 cops_surveillance_parameters(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
2917
2918      proto_tree *stt;
2919      guint8 *bcid_str;
2920
2921      /* Create a subtree */
2922      stt = info_to_cops_subtree(tvb,st,n,offset,"Electronic Surveillance Parameters");
2923      offset += 4;
2924
2925      /* DF IP Address for CDC */
2926      info_to_display(tvb,stt,offset,4,"DF IP Address for CDC", NULL,FMT_IPv4,&hf_cops_pc_dfcdc_ip);
2927      offset += 4;
2928
2929      /* DF IP Port for CDC */
2930      info_to_display(tvb,stt,offset,2,"DF IP Port for CDC",NULL,FMT_DEC,&hf_cops_pc_dfcdc_ip_port);
2931      offset += 2;
2932
2933      /* Flags */
2934      info_to_display(tvb,stt,offset,2,"Flags",NULL,FMT_HEX,&hf_cops_pc_gate_spec_flags);
2935      offset += 2;
2936
2937      /* DF IP Address for CCC */
2938      info_to_display(tvb,stt,offset,4,"DF IP Address for CCC", NULL,FMT_IPv4,&hf_cops_pc_dfccc_ip);
2939      offset += 4;
2940
2941      /* DF IP Port for CCC */
2942      info_to_display(tvb,stt,offset,2,"DF IP Port for CCC",NULL,FMT_DEC,&hf_cops_pc_dfccc_ip_port);
2943      offset += 2;
2944
2945      /* Reserved */
2946      info_to_display(tvb,stt,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
2947      offset += 2;
2948
2949      /* CCCID */
2950      info_to_display(tvb,stt,offset,4,"CCCID", NULL,FMT_DEC,&hf_cops_pc_dfccc_id);
2951      offset += 4;
2952
2953      /* BCID Timestamp */
2954      info_to_display(tvb,stt,offset,4,"BCID - Timestamp",NULL,FMT_HEX,&hf_cops_pc_bcid_ts);
2955      offset += 4;
2956
2957      /* BCID Element ID */
2958      bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
2959      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Element ID",bcid_str);
2960      offset += 8;
2961
2962      /* BCID Time Zone */
2963      bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
2964      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Time Zone",bcid_str);
2965      offset += 8;
2966
2967      /* BCID Event Counter */
2968      info_to_display(tvb,stt,offset,4,"BCID - Event Counter",NULL,FMT_DEC,&hf_cops_pc_bcid_ev);
2969 }
2970
2971 /* Cops - Section : Event Gereration-Info */
2972 static void
2973 cops_event_generation_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
2974
2975      proto_tree *stt;
2976      guint8 *bcid_str;
2977
2978      /* Create a subtree */
2979      stt = info_to_cops_subtree(tvb,st,n,offset,"Event Generation Info");
2980      offset += 4;
2981
2982      /* Primary Record Keeping Server IP Address */
2983      info_to_display(tvb,stt,offset,4,"PRKS IP Address", NULL,FMT_IPv4,&hf_cops_pc_prks_ip);
2984      offset += 4;
2985
2986      /* Primary Record Keeping Server IP Port */
2987      info_to_display(tvb,stt,offset,2,"PRKS IP Port",NULL,FMT_DEC,&hf_cops_pc_prks_ip_port);
2988      offset += 2;
2989
2990      /* Flags */
2991      info_to_display(tvb,stt,offset,1,"Flags",NULL,FMT_HEX,&hf_cops_pc_gate_spec_flags);
2992      offset += 1;
2993
2994      /* Reserved */
2995      info_to_display(tvb,stt,offset,1,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
2996      offset += 1;
2997
2998      /* Secondary Record Keeping Server IP Address */
2999      info_to_display(tvb,stt,offset,4,"SRKS IP Address", NULL,FMT_IPv4,&hf_cops_pc_srks_ip);
3000      offset += 4;
3001
3002      /* Secondary Record Keeping Server IP Port */
3003      info_to_display(tvb,stt,offset,2,"SRKS IP Port",NULL,FMT_DEC,&hf_cops_pc_srks_ip_port);
3004      offset += 2;
3005
3006      /* Flags */
3007      info_to_display(tvb,stt,offset,1,"Flags",NULL,FMT_DEC,&hf_cops_pc_gate_spec_flags);
3008      offset += 1;
3009
3010      /* Reserved */
3011      info_to_display(tvb,stt,offset,1,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
3012      offset += 1;
3013
3014      /* BCID Timestamp */
3015      info_to_display(tvb,stt,offset,4,"BCID - Timestamp",NULL,FMT_HEX,&hf_cops_pc_bcid_ts);
3016      offset += 4;
3017
3018      /* BCID Element ID */
3019      bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
3020      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Element ID",bcid_str);
3021      offset += 8;
3022
3023      /* BCID Time Zone */
3024      bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
3025      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Time Zone",bcid_str);
3026      offset += 8;
3027
3028      /* BCID Event Counter */
3029      info_to_display(tvb,stt,offset,4,"BCID - Event Counter",NULL,FMT_DEC,&hf_cops_pc_bcid_ev);
3030 }
3031
3032 /* Cops - Section : Remote Gate */
3033 static void
3034 cops_remote_gate_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
3035
3036      proto_tree *stt;
3037
3038      /* Create a subtree */
3039      stt = info_to_cops_subtree(tvb,st,n,offset,"Remote Gate Info");
3040      offset += 4;
3041
3042      /* CMTS IP Address */
3043      info_to_display(tvb,stt,offset,4,"CMTS IP Address", NULL,FMT_IPv4,&hf_cops_pc_cmts_ip);
3044      offset += 4;
3045
3046      /* CMTS IP Port */
3047      info_to_display(tvb,stt,offset,2,"CMTS IP Port",NULL,FMT_DEC,&hf_cops_pc_cmts_ip_port);
3048      offset += 2;
3049
3050      /* Flags */
3051      info_to_display(tvb,stt,offset,2,"Flags",NULL,FMT_DEC,&hf_cops_pc_remote_flags);
3052      offset += 2;
3053
3054      /* Remote Gate ID */
3055      info_to_display(tvb,stt,offset,4,"Remote Gate ID", NULL,FMT_HEX,&hf_cops_pc_remote_gate_id);
3056      offset += 4;
3057
3058      /* Algorithm */
3059      info_to_display(tvb,stt,offset,2,"Algorithm", NULL,FMT_DEC,&hf_cops_pc_algorithm);
3060      offset += 2;
3061
3062      /* Reserved */
3063      info_to_display(tvb,stt,offset,4,"Reserved", NULL,FMT_HEX,&hf_cops_pc_reserved);
3064      offset += 4;
3065
3066      /* Security Key */
3067      info_to_display(tvb,stt,offset,4,"Security Key", NULL,FMT_HEX,&hf_cops_pc_key);
3068      offset += 4;
3069
3070      /* Security Key */
3071      info_to_display(tvb,stt,offset,4,"Security Key (cont)", NULL,FMT_HEX,&hf_cops_pc_key);
3072      offset += 4;
3073
3074      /* Security Key */
3075      info_to_display(tvb,stt,offset,4,"Security Key (cont)", NULL,FMT_HEX,&hf_cops_pc_key);
3076      offset += 4;
3077
3078      /* Security Key */
3079      info_to_display(tvb,stt,offset,4,"Security Key (cont)", NULL,FMT_HEX,&hf_cops_pc_key);
3080 }
3081
3082 /* Cops - Section : PacketCable reason */
3083 static void
3084 cops_packetcable_reason(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
3085
3086      proto_tree *stt;
3087      guint16  code16;
3088
3089      /* Create a subtree */
3090      stt = info_to_cops_subtree(tvb,st,n,offset,"PacketCable Reason");
3091      offset += 4;
3092
3093      /* Reason Code */
3094      code16 = tvb_get_ntohs(tvb,offset);
3095      proto_tree_add_uint_format(stt, hf_cops_pc_reason_code,tvb, offset, 2,
3096        code16, "%-28s : %s (%u)","Reason Code",
3097        val_to_str(code16, table_cops_reason_code, "Unknown (0x%04x)"),code16);
3098      offset += 2;
3099
3100      if ( code16 == 0 ) {
3101         /* Reason Sub Code with Delete */
3102         info_to_display(tvb,stt,offset,2,"Reason Sub Code",table_cops_reason_subcode_delete,FMT_DEC,&hf_cops_pc_delete_subcode);
3103      } else {
3104         /* Reason Sub Code with Close */
3105         info_to_display(tvb,stt,offset,2,"Reason Sub Code",table_cops_reason_subcode_close,FMT_DEC,&hf_cops_pc_close_subcode);
3106      }
3107 }
3108
3109 /* Cops - Section : PacketCable error */
3110 static void
3111 cops_packetcable_error(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
3112
3113      proto_tree *stt;
3114
3115      /* Create a subtree */
3116      stt = info_to_cops_subtree(tvb,st,n,offset,"PacketCable Error");
3117      offset += 4;
3118
3119      /* Error Code */
3120      info_to_display(tvb,stt,offset,2,"Error Code",table_cops_packetcable_error,FMT_DEC,&hf_cops_pc_packetcable_err_code);
3121      offset += 2;
3122
3123      /* Error Sub Code */
3124      info_to_display(tvb,stt,offset,2,"Error Sub Code",NULL,FMT_HEX,&hf_cops_pc_packetcable_sub_code);
3125
3126 }
3127
3128 /* Cops - Section : Multimedia Transaction ID */
3129 static void
3130 cops_mm_transaction_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *st, guint8 op_code, guint n, guint32 offset) {
3131
3132      proto_tree *stt;
3133      guint16  code16;
3134      char info[50];
3135
3136      /* Create a subtree */
3137      stt = info_to_cops_subtree(tvb,st,n,offset,"MM Transaction ID");
3138      offset += 4;
3139
3140      /* Transaction Identifier */
3141      info_to_display(tvb,stt,offset,2,"Multimedia Transaction Identifier", NULL,FMT_DEC,&hf_cops_pc_transaction_id);
3142      offset +=2;
3143
3144      /* Gate Command Type */
3145      code16 = tvb_get_ntohs(tvb,offset);
3146      proto_tree_add_uint_format(stt, hf_cops_pc_gate_command_type,tvb, offset, 2,
3147             code16,"%-28s : %s (%u)", "Gate Command Type",
3148             val_to_str(code16,table_cops_mm_transaction_id, "Unknown (0x%04x)"),code16);
3149
3150      /* Write the right data into the 'info field' on the Gui */
3151      g_snprintf(info,sizeof(info),"COPS %-20s - %s",val_to_str(op_code,cops_op_code_vals, "Unknown"),
3152                 val_to_str(code16,table_cops_mm_transaction_id, "Unknown"));
3153
3154      col_clear(pinfo->cinfo, COL_INFO);
3155      col_add_str(pinfo->cinfo, COL_INFO,info);
3156 }
3157
3158 /* Cops - Section : AMID */
3159 static void
3160 cops_amid(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
3161
3162      proto_tree *stt;
3163
3164      /* Create a subtree */
3165      stt = info_to_cops_subtree(tvb,st,n,offset,"AMID");
3166      offset += 4;
3167
3168      /* Application Type */
3169      info_to_display(tvb,stt,offset,2,"Application Manager ID Application Type", NULL,FMT_DEC,&hf_cops_pcmm_amid_app_type);
3170      offset += 2;
3171
3172      /* Application Manager Tag */
3173      info_to_display(tvb,stt,offset,2,"Application Manager ID Application Manager Tag", NULL,FMT_DEC,&hf_cops_pcmm_amid_am_tag);
3174 }
3175
3176
3177 /* Cops - Section : Multimedia Gate Specifications */
3178 static void
3179 cops_mm_gate_spec(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
3180      proto_item *ti;
3181      proto_tree *stt, *object_tree;
3182      guint8 gs_flags;
3183
3184      /* Create a subtree */
3185      stt = info_to_cops_subtree(tvb,st,n,offset,"Gate Spec");
3186      offset += 4;
3187
3188      /* Flags */
3189      gs_flags = tvb_get_guint8(tvb, offset);
3190      ti = info_to_display(tvb,stt,offset,1,"Flags",NULL,FMT_HEX,&hf_cops_pcmm_gate_spec_flags);
3191      object_tree = proto_item_add_subtree(ti, ett_cops_subtree );
3192      proto_tree_add_text(object_tree, tvb, offset, 1, "%s gate",
3193             decode_boolean_bitfield(gs_flags, 1 << 0, 8,
3194                     "Upstream", "Downstream"));
3195      proto_tree_add_text(object_tree, tvb, offset, 1, "%s DSCP/TOS overwrite",
3196             decode_boolean_bitfield(gs_flags, 1 << 1, 8,
3197                     "Enable", "Disable"));
3198      offset += 1;
3199
3200      /* DiffServ Code Point */
3201      info_to_display(tvb,stt,offset,1,"DS Field (DSCP or TOS)",NULL,FMT_HEX,&hf_cops_pcmm_gate_spec_dscp_tos_field);
3202      offset += 1;
3203
3204      /* DiffServ Code Point Mask */
3205      info_to_display(tvb,stt,offset,1,"DS Field (DSCP or TOS) Mask",NULL,FMT_HEX,&hf_cops_pcmm_gate_spec_dscp_tos_mask);
3206      offset += 1;
3207
3208      /* Session Class */
3209      ti = info_to_display(tvb,stt,offset,1,"Session Class",table_cops_session_class,FMT_DEC,&hf_cops_pcmm_gate_spec_session_class_id);
3210      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3211      proto_tree_add_item(object_tree, hf_cops_pcmm_gate_spec_session_class_id_priority, tvb, offset, 1, FALSE);
3212      proto_tree_add_item(object_tree, hf_cops_pcmm_gate_spec_session_class_id_preemption, tvb, offset, 1, FALSE);
3213      proto_tree_add_item(object_tree, hf_cops_pcmm_gate_spec_session_class_id_configurable, tvb, offset, 1, FALSE);
3214      offset += 1;
3215
3216      /* Timer T1 Value */
3217      info_to_display(tvb,stt,offset,2,"Timer T1 Value (sec)",NULL,FMT_DEC,&hf_cops_pcmm_gate_spec_timer_t1);
3218      offset += 2;
3219
3220      /* Timer T2 Value */
3221      info_to_display(tvb,stt,offset,2,"Timer T2 Value (sec)",NULL,FMT_DEC,&hf_cops_pcmm_gate_spec_timer_t2);
3222      offset += 2;
3223
3224      /* Timer T3 Value */
3225      info_to_display(tvb,stt,offset,2,"Timer T3 Value (sec)",NULL,FMT_DEC,&hf_cops_pcmm_gate_spec_timer_t3);
3226      offset += 2;
3227
3228      /* Timer T4 Value */
3229      info_to_display(tvb,stt,offset,2,"Timer T4 Value (sec)",NULL,FMT_DEC,&hf_cops_pcmm_gate_spec_timer_t4);
3230      offset += 2;
3231 }
3232
3233 /* Cops - Section : Classifier */
3234 static void
3235 cops_classifier(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset, gboolean extended) {
3236
3237     proto_tree *stt;
3238
3239     /* Create a subtree */
3240     stt = info_to_cops_subtree(tvb,st,n,offset,
3241         extended ? "Extended Classifier" : "Classifier");
3242     offset += 4;
3243
3244     /* Protocol ID */
3245     info_to_display(tvb,stt,offset,2,"Protocol ID",NULL,FMT_DEC,&hf_cops_pcmm_classifier_protocol_id);
3246     offset += 2;
3247
3248     /* DiffServ Code Point */
3249     info_to_display(tvb,stt,offset,1,"DS Field (DSCP or TOS)",NULL,FMT_HEX,&hf_cops_pcmm_classifier_dscp_tos_field);
3250     offset += 1;
3251
3252     /* DiffServ Code Point Mask */
3253     info_to_display(tvb,stt,offset,1,"DS Field (DSCP or TOS) Mask",NULL,FMT_HEX,&hf_cops_pcmm_classifier_dscp_tos_mask);
3254     offset += 1;
3255
3256     /* Source IP Address */
3257     info_to_display(tvb,stt,offset,4,"Source IP Address",NULL,FMT_IPv4,&hf_cops_pcmm_classifier_src_addr);
3258     offset += 4;
3259
3260     if (extended) {
3261         /* Source Mask */
3262         info_to_display(tvb,stt,offset,4,"Source Mask",NULL,FMT_IPv4,&hf_cops_pcmm_classifier_src_mask);
3263         offset += 4;
3264     }
3265
3266     /* Destination IP Address */
3267     info_to_display(tvb,stt,offset,4,"Destination IP Address",NULL,FMT_IPv4,&hf_cops_pcmm_classifier_dst_addr);
3268     offset += 4;
3269
3270     if (extended) {
3271         /* Destination Mask */
3272         info_to_display(tvb,stt,offset,4,"Destination Mask",NULL,FMT_IPv4,&hf_cops_pcmm_classifier_dst_mask);
3273         offset += 4;
3274     }
3275
3276     /* Source IP Port */
3277     info_to_display(tvb,stt,offset,2,"Source IP Port",NULL,FMT_DEC,&hf_cops_pcmm_classifier_src_port);
3278     offset += 2;
3279
3280     if (extended) {
3281         /* Source Port End */
3282         info_to_display(tvb,stt,offset,2,"Source Port End",NULL,FMT_DEC,&hf_cops_pcmm_classifier_src_port_end);
3283         offset += 2;
3284     }
3285
3286     /* Destination IP Port */
3287     info_to_display(tvb,stt,offset,2,"Destination IP Port",NULL,FMT_DEC,&hf_cops_pcmm_classifier_dst_port);
3288     offset += 2;
3289
3290     if (extended) {
3291         /* Destination Port End */
3292         info_to_display(tvb,stt,offset,2,"Destination Port End",NULL,FMT_DEC,&hf_cops_pcmm_classifier_dst_port_end);
3293         offset += 2;
3294     }
3295
3296     if (extended) {
3297         /* ClassifierID */
3298         info_to_display(tvb,stt,offset,2,"ClassifierID",NULL,FMT_HEX,&hf_cops_pcmm_classifier_classifier_id);
3299         offset += 2;
3300     }
3301
3302     /* Priority */
3303     info_to_display(tvb,stt,offset,1,"Priority",NULL,FMT_HEX,&hf_cops_pcmm_classifier_priority);
3304     offset += 1;
3305
3306     if (extended) {
3307         /* Activation State */
3308         info_to_display(tvb,stt,offset,1,"Activation State",NULL,FMT_HEX,&hf_cops_pcmm_classifier_activation_state);
3309         offset += 1;
3310
3311         /* Action */
3312         info_to_display(tvb,stt,offset,1,"Action",NULL,FMT_HEX,&hf_cops_pcmm_classifier_action);
3313         offset += 1;
3314     }
3315
3316     /* 3 octets Not specified */
3317     offset += 3;
3318 }
3319
3320 /* Cops - Section : IPv6 Classifier */
3321 static void
3322 cops_ipv6_classifier(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
3323
3324     proto_tree *stt;
3325
3326     /* Create a subtree */
3327     stt = info_to_cops_subtree(tvb,st,n,offset, "IPv6 Classifier");
3328     offset += 4;
3329
3330     /* Reserved/Flags */
3331     info_to_display(tvb,stt,offset,1,"Flags",NULL,FMT_HEX,&hf_cops_pcmm_classifier_flags);
3332     offset += 1;
3333
3334     /* tc-low */
3335     info_to_display(tvb,stt,offset,1,"tc-low",NULL,FMT_HEX,&hf_cops_pcmm_classifier_tc_low);
3336     offset += 1;
3337
3338     /* tc-high */
3339     info_to_display(tvb,stt,offset,1,"tc-high",NULL,FMT_HEX,&hf_cops_pcmm_classifier_tc_high);
3340     offset += 1;
3341
3342     /* tc-mask */
3343     info_to_display(tvb,stt,offset,1,"tc-mask",NULL,FMT_HEX,&hf_cops_pcmm_classifier_tc_mask);
3344     offset += 1;
3345
3346     /* Flow Label */
3347     info_to_display(tvb,stt,offset,4,"Flow Label",NULL,FMT_HEX,&hf_cops_pcmm_classifier_flow_label);
3348     offset += 4;
3349
3350     /* Next Header Type */
3351     info_to_display(tvb,stt,offset,2,"Next Header Type",NULL,FMT_DEC,&hf_cops_pcmm_classifier_next_header_type);
3352     offset += 2;
3353
3354     /* Source Prefix Length */
3355     info_to_display(tvb,stt,offset,1,"Source Prefix Length",NULL,FMT_DEC,&hf_cops_pcmm_classifier_source_prefix_length);
3356     offset += 1;
3357
3358     /* Destination Prefix Length */
3359     info_to_display(tvb,stt,offset,1,"Destination Prefix Length",NULL,FMT_DEC,&hf_cops_pcmm_classifier_destination_prefix_length);
3360     offset += 1;
3361
3362     /* Source IP Address */
3363     info_to_display(tvb,stt,offset,16,"IPv6 Source Address",NULL,FMT_IPv6,&hf_cops_pcmm_classifier_src_addr_v6);
3364     offset += 16;
3365
3366     /* Destination IP Address */
3367     info_to_display(tvb,stt,offset,16,"IPv6 Destination Address",NULL,FMT_IPv6,&hf_cops_pcmm_classifier_dst_addr_v6);
3368     offset += 16;
3369
3370     /* Source IP Port */
3371     info_to_display(tvb,stt,offset,2,"Source Port Start",NULL,FMT_DEC,&hf_cops_pcmm_classifier_src_port);
3372     offset += 2;
3373
3374         /* Source Port End */
3375         info_to_display(tvb,stt,offset,2,"Source Port End",NULL,FMT_DEC,&hf_cops_pcmm_classifier_src_port_end);
3376         offset += 2;
3377
3378     /* Destination IP Port */
3379     info_to_display(tvb,stt,offset,2,"Destination Port Start",NULL,FMT_DEC,&hf_cops_pcmm_classifier_dst_port);
3380     offset += 2;
3381
3382         /* Destination Port End */
3383         info_to_display(tvb,stt,offset,2,"Destination Port End",NULL,FMT_DEC,&hf_cops_pcmm_classifier_dst_port_end);
3384         offset += 2;
3385
3386         /* ClassifierID */
3387         info_to_display(tvb,stt,offset,2,"ClassifierID",NULL,FMT_HEX,&hf_cops_pcmm_classifier_classifier_id);
3388         offset += 2;
3389
3390     /* Priority */
3391     info_to_display(tvb,stt,offset,1,"Priority",NULL,FMT_HEX,&hf_cops_pcmm_classifier_priority);
3392     offset += 1;
3393
3394         /* Activation State */
3395         info_to_display(tvb,stt,offset,1,"Activation State",NULL,FMT_HEX,&hf_cops_pcmm_classifier_activation_state);
3396         offset += 1;
3397
3398         /* Action */
3399         info_to_display(tvb,stt,offset,1,"Action",NULL,FMT_HEX,&hf_cops_pcmm_classifier_action);
3400         offset += 1;
3401
3402     /* 3 octets Not specified */
3403     offset += 3;
3404 }
3405
3406 /* Cops - Section : Gate Specifications */
3407 static void
3408 cops_flow_spec(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
3409      proto_item *ti;
3410      proto_tree *stt, *object_tree;
3411
3412      /* Create a subtree */
3413      stt = info_to_cops_subtree(tvb,st,n,offset,"Flow Spec");
3414      offset += 4;
3415
3416      /* Envelope */
3417      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_flow_spec_envelope);
3418      offset += 1;
3419
3420      /* Service Number */
3421      info_to_display(tvb,stt,offset,1,"Service Number",NULL,FMT_DEC,&hf_cops_pcmm_flow_spec_service_number);
3422      offset += 1;
3423
3424      /* Reserved */
3425      info_to_display(tvb,stt,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
3426      offset += 2;
3427
3428      /* Authorized Envelope */
3429      ti = proto_tree_add_text(stt, tvb, offset, 28, "Authorized Envelope");
3430      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3431
3432      /* Token Bucket Rate */
3433      info_to_display(tvb,object_tree,offset,4,"Token Bucket Rate",NULL,FMT_FLT,&hf_cops_pc_token_bucket_rate);
3434      offset += 4;
3435
3436      /* Token Bucket Size */
3437      info_to_display(tvb,object_tree,offset,4,"Token Bucket Size",NULL,FMT_FLT,&hf_cops_pc_token_bucket_size);
3438      offset += 4;
3439
3440      /* Peak Data Rate */
3441      info_to_display(tvb,object_tree,offset,4,"Peak Data Rate",NULL,FMT_FLT,&hf_cops_pc_peak_data_rate);
3442      offset += 4;
3443
3444      /* Minimum Policed Unit */
3445      info_to_display(tvb,object_tree,offset,4,"Minimum Policed Unit",NULL,FMT_DEC,&hf_cops_pc_min_policed_unit);
3446      offset += 4;
3447
3448      /* Maximum Packet Size */
3449      info_to_display(tvb,object_tree,offset,4,"Maximum Packet Size",NULL,FMT_DEC,&hf_cops_pc_max_packet_size);
3450      offset += 4;
3451
3452      /* Rate */
3453      info_to_display(tvb,object_tree,offset,4,"Rate",NULL,FMT_FLT,&hf_cops_pc_spec_rate);
3454      offset += 4;
3455
3456      /* Slack Term */
3457      info_to_display(tvb,object_tree,offset,4,"Slack Term",NULL,FMT_DEC,&hf_cops_pc_slack_term);
3458      offset += 4;
3459
3460      if (n < 64) return;
3461
3462      /* Reserved Envelope */
3463      ti = proto_tree_add_text(stt, tvb, offset, 28, "Reserved Envelope");
3464      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3465
3466      /* Token Bucket Rate */
3467      info_to_display(tvb,object_tree,offset,4,"Token Bucket Rate",NULL,FMT_FLT,&hf_cops_pc_token_bucket_rate);
3468      offset += 4;
3469
3470      /* Token Bucket Size */
3471      info_to_display(tvb,object_tree,offset,4,"Token Bucket Size",NULL,FMT_FLT,&hf_cops_pc_token_bucket_size);
3472      offset += 4;
3473
3474      /* Peak Data Rate */
3475      info_to_display(tvb,object_tree,offset,4,"Peak Data Rate",NULL,FMT_FLT,&hf_cops_pc_peak_data_rate);
3476      offset += 4;
3477
3478      /* Minimum Policed Unit */
3479      info_to_display(tvb,object_tree,offset,4,"Minimum Policed Unit",NULL,FMT_DEC,&hf_cops_pc_min_policed_unit);
3480      offset += 4;
3481
3482      /* Maximum Packet Size */
3483      info_to_display(tvb,object_tree,offset,4,"Maximum Packet Size",NULL,FMT_DEC,&hf_cops_pc_max_packet_size);
3484      offset += 4;
3485
3486      /* Rate */
3487      info_to_display(tvb,object_tree,offset,4,"Rate",NULL,FMT_FLT,&hf_cops_pc_spec_rate);
3488      offset += 4;
3489
3490      /* Slack Term */
3491      info_to_display(tvb,object_tree,offset,4,"Slack Term",NULL,FMT_DEC,&hf_cops_pc_slack_term);
3492      offset += 4;
3493
3494      if (n < 92) return;
3495
3496      /* Committed Envelope */
3497      ti = proto_tree_add_text(stt, tvb, offset, 28, "Committed Envelope");
3498      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3499
3500      /* Token Bucket Rate */
3501      info_to_display(tvb,object_tree,offset,4,"Token Bucket Rate",NULL,FMT_FLT,&hf_cops_pc_token_bucket_rate);
3502      offset += 4;
3503
3504      /* Token Bucket Size */
3505      info_to_display(tvb,object_tree,offset,4,"Token Bucket Size",NULL,FMT_FLT,&hf_cops_pc_token_bucket_size);
3506      offset += 4;
3507
3508      /* Peak Data Rate */
3509      info_to_display(tvb,object_tree,offset,4,"Peak Data Rate",NULL,FMT_FLT,&hf_cops_pc_peak_data_rate);
3510      offset += 4;
3511
3512      /* Minimum Policed Unit */
3513      info_to_display(tvb,object_tree,offset,4,"Minimum Policed Unit",NULL,FMT_DEC,&hf_cops_pc_min_policed_unit);
3514      offset += 4;
3515
3516      /* Maximum Packet Size */
3517      info_to_display(tvb,object_tree,offset,4,"Maximum Packet Size",NULL,FMT_DEC,&hf_cops_pc_max_packet_size);
3518      offset += 4;
3519
3520      /* Rate */
3521      info_to_display(tvb,object_tree,offset,4,"Rate",NULL,FMT_FLT,&hf_cops_pc_spec_rate);
3522      offset += 4;
3523
3524      /* Slack Term */
3525      info_to_display(tvb,object_tree,offset,4,"Slack Term",NULL,FMT_DEC,&hf_cops_pc_slack_term);
3526 }
3527
3528 /* Cops - Section : DOCSIS Service Class Name */
3529 static void
3530 cops_docsis_service_class_name(tvbuff_t *tvb, proto_tree *st, guint object_len, guint32 offset) {
3531
3532      proto_tree *stt;
3533
3534      /* Create a subtree */
3535      stt = info_to_cops_subtree(tvb,st,object_len,offset,"DOCSIS Service Class Name");
3536      offset += 4;
3537
3538      /* Envelope */
3539      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
3540      offset += 1;
3541
3542      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
3543      offset += 3;
3544
3545      if (object_len >= 12) {
3546             proto_tree_add_item(stt, hf_cops_pcmm_docsis_scn, tvb, offset, object_len - 8, FALSE);
3547             offset += object_len - 8;
3548      } else {
3549             proto_tree_add_text(stt, tvb, offset - 8, 2, "Invalid object length: %u", object_len);
3550      }
3551 }
3552
3553 /* New functions were made with the i04 suffix to maintain backward compatibility with I03
3554 *
3555 *  BEGIN PCMM I04
3556 *
3557 */
3558
3559 /* Cops - Section : Best Effort Service */
3560 static void
3561 cops_best_effort_service_i04_i05(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset, gboolean i05) {
3562      proto_item *ti;
3563      proto_tree *stt, *object_tree;
3564
3565      /* Create a subtree */
3566      stt = info_to_cops_subtree(tvb,st,n,offset,"Best Effort Service");
3567      offset += 4;
3568
3569      /* Envelope */
3570      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
3571      offset += 1;
3572
3573      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
3574      offset += 3;
3575
3576      /* Authorized Envelope */
3577      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 36 : 32, "Authorized Envelope");
3578      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3579
3580      /* Traffic Priority */
3581      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
3582      offset += 1;
3583
3584      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
3585      offset += 3;
3586
3587      /* Request Transmission Policy */
3588      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
3589      offset += 4;
3590
3591      /* Maximum Sustained Traffic Rate */
3592      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
3593      offset += 4;
3594
3595      /* Maximum Traffic Burst */
3596      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
3597      offset += 4;
3598
3599      /* Minimum Reserved Traffic Rate */
3600      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
3601      offset += 4;
3602
3603      /* Assumed Minimum Reserved Traffic Rate Packet Size */
3604      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
3605      offset += 2;
3606
3607      /* Maximum Concatenated Burst */
3608      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
3609      offset += 2;
3610
3611      /* Required Attribute Mask */
3612      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
3613      offset += 4;
3614
3615      /* Forbidden Attribute Mask */
3616      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
3617      offset += 4;
3618
3619      if (i05) {
3620        /* Attribute Aggregation Rule Mask */
3621        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
3622        offset += 4;
3623      }
3624
3625      if (n < 56) return;
3626
3627      /* Reserved Envelope */
3628      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 36 : 32, "Reserved Envelope");
3629      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3630
3631      /* Traffic Priority */
3632      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
3633      offset += 1;
3634
3635      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
3636      offset += 3;
3637
3638      /* Request Transmission Policy */
3639      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
3640      offset += 4;
3641
3642      /* Maximum Sustained Traffic Rate */
3643      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
3644      offset += 4;
3645
3646      /* Maximum Traffic Burst */
3647      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
3648      offset += 4;
3649
3650      /* Minimum Reserved Traffic Rate */
3651      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
3652      offset += 4;
3653
3654      /* Assumed Minimum Reserved Traffic Rate Packet Size */
3655      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
3656      offset += 2;
3657
3658      /* Maximum Concatenated Burst */
3659      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
3660      offset += 2;
3661
3662      /* Required Attribute Mask */
3663      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
3664      offset += 4;
3665
3666      /* Forbidden Attribute Mask */
3667      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
3668      offset += 4;
3669
3670      if (i05) {
3671          /* Attribute Aggregation Rule Mask */
3672          info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
3673          offset += 4;
3674      }
3675
3676      if (n < 80) return;
3677
3678      /* Committed Envelope */
3679      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 36 : 32, "Committed Envelope");
3680      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3681
3682      /* Traffic Priority */
3683      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
3684      offset += 1;
3685
3686      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
3687      offset += 3;
3688
3689      /* Request Transmission Policy */
3690      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
3691      offset += 4;
3692
3693      /* Maximum Sustained Traffic Rate */
3694      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
3695      offset += 4;
3696
3697      /* Maximum Traffic Burst */
3698      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
3699      offset += 4;
3700
3701      /* Minimum Reserved Traffic Rate */
3702      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
3703      offset += 4;
3704
3705      /* Assumed Minimum Reserved Traffic Rate Packet Size */
3706      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
3707      offset += 2;
3708
3709      /* Maximum Concatenated Burst */
3710      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
3711      offset += 2;
3712
3713      /* Required Attribute Mask */
3714      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
3715      offset += 4;
3716
3717      /* Forbidden Attribute Mask */
3718      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
3719      offset += 4;
3720
3721      if (i05) {
3722          /* Attribute Aggregation Rule Mask */
3723          info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
3724          offset += 4;
3725      }
3726 }
3727
3728 /* Cops - Section : Non-Real-Time Polling Service */
3729 static void
3730 cops_non_real_time_polling_service_i04_i05(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset, gboolean i05) {
3731      proto_item *ti;
3732      proto_tree *stt, *object_tree;
3733
3734      /* Create a subtree */
3735      stt = info_to_cops_subtree(tvb,st,n,offset,"Non-Real-Time Polling Service");
3736      offset += 4;
3737
3738      /* Envelope */
3739      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
3740      offset += 1;
3741
3742      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
3743      offset += 3;
3744
3745      /* Authorized Envelope */
3746      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Authorized Envelope");
3747      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3748
3749      /* Traffic Priority */
3750      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
3751      offset += 1;
3752
3753      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
3754      offset += 3;
3755
3756      /* Request Transmission Policy */
3757      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
3758      offset += 4;
3759
3760      /* Maximum Sustained Traffic Rate */
3761      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
3762      offset += 4;
3763
3764      /* Maximum Traffic Burst */
3765      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
3766      offset += 4;
3767
3768      /* Minimum Reserved Traffic Rate */
3769      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
3770      offset += 4;
3771
3772      /* Assumed Minimum Reserved Traffic Rate Packet Size */
3773      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
3774      offset += 2;
3775
3776      /* Maximum Concatenated Burst */
3777      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
3778      offset += 2;
3779
3780      /* Nominal Polling Interval */
3781      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
3782      offset += 4;
3783
3784      /* Required Attribute Mask */
3785      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
3786      offset += 4;
3787
3788      /* Forbidden Attribute Mask */
3789      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
3790      offset += 4;
3791
3792      if (i05) {
3793        /* Attribute Aggregation Rule Mask */
3794        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
3795        offset += 4;
3796      }
3797
3798      if (n < 64) return;
3799
3800      /* Reserved Envelope */
3801      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Reserved Envelope");
3802      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3803
3804      /* Traffic Priority */
3805      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
3806      offset += 1;
3807
3808      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
3809      offset += 3;
3810
3811      /* Request Transmission Policy */
3812      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
3813      offset += 4;
3814
3815      /* Maximum Sustained Traffic Rate */
3816      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
3817      offset += 4;
3818
3819      /* Maximum Traffic Burst */
3820      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
3821      offset += 4;
3822
3823      /* Minimum Reserved Traffic Rate */
3824      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
3825      offset += 4;
3826
3827      /* Assumed Minimum Reserved Traffic Rate Packet Size */
3828      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
3829      offset += 2;
3830
3831      /* Maximum Concatenated Burst */
3832      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
3833      offset += 2;
3834
3835      /* Nominal Polling Interval */
3836      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
3837      offset += 4;
3838
3839      /* Required Attribute Mask */
3840      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
3841      offset += 4;
3842
3843      /* Forbidden Attribute Mask */
3844      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
3845      offset += 4;
3846
3847      if (i05) {
3848        /* Attribute Aggregation Rule Mask */
3849        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
3850        offset += 4;
3851      }
3852
3853      if (n < 92) return;
3854
3855      /* Committed Envelope */
3856      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Committed Envelope");
3857      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3858
3859      /* Traffic Priority */
3860      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
3861      offset += 1;
3862
3863      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
3864      offset += 3;
3865
3866      /* Request Transmission Policy */
3867      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
3868      offset += 4;
3869
3870      /* Maximum Sustained Traffic Rate */
3871      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
3872      offset += 4;
3873
3874      /* Maximum Traffic Burst */
3875      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
3876      offset += 4;
3877
3878      /* Minimum Reserved Traffic Rate */
3879      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
3880      offset += 4;
3881
3882      /* Assumed Minimum Reserved Traffic Rate Packet Size */
3883      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
3884      offset += 2;
3885
3886      /* Maximum Concatenated Burst */
3887      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
3888      offset += 2;
3889
3890      /* Nominal Polling Interval */
3891      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
3892      offset += 4;
3893
3894      /* Required Attribute Mask */
3895      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
3896      offset += 4;
3897
3898      /* Forbidden Attribute Mask */
3899      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
3900      offset += 4;
3901
3902      if (i05) {
3903        /* Attribute Aggregation Rule Mask */
3904        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
3905        offset += 4;
3906      }
3907 }
3908
3909 /* Cops - Section : Real-Time Polling Service */
3910 static void
3911 cops_real_time_polling_service_i04_i05(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset, gboolean i05) {
3912      proto_item *ti;
3913      proto_tree *stt, *object_tree;
3914
3915      /* Create a subtree */
3916      stt = info_to_cops_subtree(tvb,st,n,offset,"Real-Time Polling Service");
3917      offset += 4;
3918
3919      /* Envelope */
3920      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
3921      offset += 1;
3922
3923      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
3924      offset += 3;
3925
3926      /* Authorized Envelope */
3927      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Authorized Envelope");
3928      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3929
3930      /* Request Transmission Policy */
3931      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
3932      offset += 4;
3933
3934      /* Maximum Sustained Traffic Rate */
3935      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
3936      offset += 4;
3937
3938      /* Maximum Traffic Burst */
3939      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
3940      offset += 4;
3941
3942      /* Minimum Reserved Traffic Rate */
3943      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
3944      offset += 4;
3945
3946      /* Assumed Minimum Reserved Traffic Rate Packet Size */
3947      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
3948      offset += 2;
3949
3950      /* Maximum Concatenated Burst */
3951      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
3952      offset += 2;
3953
3954      /* Nominal Polling Interval */
3955      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
3956      offset += 4;
3957
3958      /* Tolerated Poll Jitter */
3959      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
3960      offset += 4;
3961
3962      /* Required Attribute Mask */
3963      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
3964      offset += 4;
3965
3966      /* Forbidden Attribute Mask */
3967      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
3968      offset += 4;
3969
3970      if (i05) {
3971        /* Attribute Aggregation Rule Mask */
3972        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
3973        offset += 4;
3974      }
3975
3976      if (n < 64) return;
3977
3978      /* Reserved Envelope */
3979      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Reserved Envelope");
3980      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
3981
3982      /* Request Transmission Policy */
3983      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
3984      offset += 4;
3985
3986      /* Maximum Sustained Traffic Rate */
3987      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
3988      offset += 4;
3989
3990      /* Maximum Traffic Burst */
3991      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
3992      offset += 4;
3993
3994      /* Minimum Reserved Traffic Rate */
3995      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
3996      offset += 4;
3997
3998      /* Assumed Minimum Reserved Traffic Rate Packet Size */
3999      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4000      offset += 2;
4001
4002      /* Maximum Concatenated Burst */
4003      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
4004      offset += 2;
4005
4006      /* Nominal Polling Interval */
4007      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4008      offset += 4;
4009
4010      /* Tolerated Poll Jitter */
4011      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
4012      offset += 4;
4013
4014      /* Required Attribute Mask */
4015      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4016      offset += 4;
4017
4018      /* Forbidden Attribute Mask */
4019      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4020      offset += 4;
4021
4022      if (i05) {
4023        /* Attribute Aggregation Rule Mask */
4024        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4025        offset += 4;
4026      }
4027
4028      if (n < 92) return;
4029
4030      /* Committed Envelope */
4031      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Committed Envelope");
4032      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4033
4034      /* Request Transmission Policy */
4035      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4036      offset += 4;
4037
4038      /* Maximum Sustained Traffic Rate */
4039      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4040      offset += 4;
4041
4042      /* Maximum Traffic Burst */
4043      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4044      offset += 4;
4045
4046      /* Minimum Reserved Traffic Rate */
4047      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4048      offset += 4;
4049
4050      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4051      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4052      offset += 2;
4053
4054      /* Maximum Concatenated Burst */
4055      info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
4056      offset += 2;
4057
4058      /* Nominal Polling Interval */
4059      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4060      offset += 4;
4061
4062      /* Tolerated Poll Jitter */
4063      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
4064      offset += 4;
4065
4066      /* Required Attribute Mask */
4067      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4068      offset += 4;
4069
4070      /* Forbidden Attribute Mask */
4071      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4072      offset += 4;
4073
4074      if (i05) {
4075        /* Attribute Aggregation Rule Mask */
4076        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4077        offset += 4;
4078      }
4079 }
4080
4081 /* Cops - Section : Unsolicited Grant Service */
4082 static void
4083 cops_unsolicited_grant_service_i04_i05(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset, gboolean i05) {
4084      proto_item *ti;
4085      proto_tree *stt, *object_tree;
4086
4087      /* Create a subtree */
4088      stt = info_to_cops_subtree(tvb,st,n,offset,"Unsolicited Grant Service");
4089      offset += 4;
4090
4091      /* Envelope */
4092      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
4093      offset += 1;
4094
4095      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
4096      offset += 3;
4097
4098      /* Authorized Envelope */
4099      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 28 : 24, "Authorized Envelope");
4100      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4101
4102      /* Request Transmission Policy */
4103      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4104      offset += 4;
4105
4106      /* Unsolicited Grant Size */
4107      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
4108      offset += 2;
4109
4110      /* Grants Per Interval */
4111      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
4112      offset += 1;
4113
4114      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
4115      offset += 1;
4116
4117      /* Nominal Grant Interval */
4118      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
4119      offset += 4;
4120
4121      /* Tolerated Grant Jitter */
4122      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
4123      offset += 4;
4124
4125      /* Required Attribute Mask */
4126      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4127      offset += 4;
4128
4129      /* Forbidden Attribute Mask */
4130      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4131      offset += 4;
4132
4133      if (i05) {
4134        /* Attribute Aggregation Rule Mask */
4135        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4136        offset += 4;
4137      }
4138
4139      if (n < 40) return;
4140
4141      /* Reserved Envelope */
4142      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 28 : 24, "Reserved Envelope");
4143      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4144
4145      /* Request Transmission Policy */
4146      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4147      offset += 4;
4148
4149      /* Unsolicited Grant Size */
4150      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
4151      offset += 2;
4152
4153      /* Grants Per Interval */
4154      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
4155      offset += 1;
4156
4157      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
4158      offset += 1;
4159
4160      /* Nominal Grant Interval */
4161      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
4162      offset += 4;
4163
4164      /* Tolerated Grant Jitter */
4165      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
4166      offset += 4;
4167
4168      /* Required Attribute Mask */
4169      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4170      offset += 4;
4171
4172      /* Forbidden Attribute Mask */
4173      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4174      offset += 4;
4175
4176      if (i05) {
4177        /* Attribute Aggregation Rule Mask */
4178        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4179        offset += 4;
4180      }
4181
4182      if (n < 56) return;
4183
4184      /* Committed Envelope */
4185      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 28 : 24, "Committed Envelope");
4186      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4187
4188      /* Request Transmission Policy */
4189      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4190      offset += 4;
4191
4192      /* Unsolicited Grant Size */
4193      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
4194      offset += 2;
4195
4196      /* Grants Per Interval */
4197      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
4198      offset += 1;
4199
4200      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
4201      offset += 1;
4202
4203      /* Nominal Grant Interval */
4204      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
4205      offset += 4;
4206
4207      /* Tolerated Grant Jitter */
4208      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
4209      offset += 4;
4210
4211      /* Required Attribute Mask */
4212      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4213      offset += 4;
4214
4215      /* Forbidden Attribute Mask */
4216      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4217      offset += 4;
4218
4219      if (i05) {
4220        /* Attribute Aggregation Rule Mask */
4221        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4222        offset += 4;
4223      }
4224 }
4225
4226 /* Cops - Section : Unsolicited Grant Service with Activity Detection */
4227 static void
4228 cops_ugs_with_activity_detection_i04_i05(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset, gboolean i05) {
4229      proto_item *ti;
4230      proto_tree *stt, *object_tree;
4231
4232      /* Create a subtree */
4233      stt = info_to_cops_subtree(tvb,st,n,offset,"Unsolicited Grant Service with Activity Detection");
4234      offset += 4;
4235
4236      /* Envelope */
4237      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
4238      offset += 1;
4239
4240      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
4241      offset += 3;
4242
4243      /* Authorized Envelope */
4244      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 36 : 32, "Authorized Envelope");
4245      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4246
4247      /* Request Transmission Policy */
4248      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4249      offset += 4;
4250
4251      /* Unsolicited Grant Size */
4252      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
4253      offset += 2;
4254
4255      /* Grants Per Interval */
4256      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
4257      offset += 1;
4258
4259      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
4260      offset += 1;
4261
4262      /* Nominal Grant Interval */
4263      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
4264      offset += 4;
4265
4266      /* Tolerated Grant Jitter */
4267      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
4268      offset += 4;
4269
4270      /* Nominal Polling Interval */
4271      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4272      offset += 4;
4273
4274      /* Tolerated Poll Jitter */
4275      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
4276      offset += 4;
4277
4278      /* Required Attribute Mask */
4279      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4280      offset += 4;
4281
4282      /* Forbidden Attribute Mask */
4283      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4284      offset += 4;
4285
4286      if (i05) {
4287        /* Attribute Aggregation Rule Mask */
4288        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4289        offset += 4;
4290      }
4291
4292      if (n < 56) return;
4293
4294      /* Reserved Envelope */
4295      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 36 : 32, "Reserved Envelope");
4296      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4297
4298      /* Request Transmission Policy */
4299      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4300      offset += 4;
4301
4302      /* Unsolicited Grant Size */
4303      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
4304      offset += 2;
4305
4306      /* Grants Per Interval */
4307      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
4308      offset += 1;
4309
4310      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
4311      offset += 1;
4312
4313      /* Nominal Grant Interval */
4314      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
4315      offset += 4;
4316
4317      /* Tolerated Grant Jitter */
4318      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
4319      offset += 4;
4320
4321      /* Nominal Polling Interval */
4322      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4323      offset += 4;
4324
4325      /* Tolerated Poll Jitter */
4326      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
4327      offset += 4;
4328
4329      /* Required Attribute Mask */
4330      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4331      offset += 4;
4332
4333      /* Forbidden Attribute Mask */
4334      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4335      offset += 4;
4336
4337      if (i05) {
4338        /* Attribute Aggregation Rule Mask */
4339        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4340        offset += 4;
4341      }
4342
4343      if (n < 80) return;
4344
4345      /* Committed Envelope */
4346      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 36 : 32, "Committed Envelope");
4347      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4348
4349      /* Request Transmission Policy */
4350      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4351      offset += 4;
4352
4353      /* Unsolicited Grant Size */
4354      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
4355      offset += 2;
4356
4357      /* Grants Per Interval */
4358      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
4359      offset += 1;
4360
4361      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
4362      offset += 1;
4363
4364      /* Nominal Grant Interval */
4365      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
4366      offset += 4;
4367
4368      /* Tolerated Grant Jitter */
4369      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
4370      offset += 4;
4371
4372      /* Nominal Polling Interval */
4373      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4374      offset += 4;
4375
4376      /* Tolerated Poll Jitter */
4377      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
4378      offset += 4;
4379
4380      /* Required Attribute Mask */
4381      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4382      offset += 4;
4383
4384      /* Forbidden Attribute Mask */
4385      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4386      offset += 4;
4387
4388      if (i05) {
4389        /* Attribute Aggregation Rule Mask */
4390        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4391        offset += 4;
4392      }
4393 }
4394
4395 /* Cops - Section : Downstream Service */
4396 static void
4397 cops_downstream_service_i04_i05(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset, gboolean i05) {
4398      proto_item *ti;
4399      proto_tree *stt, *object_tree;
4400
4401      /* Create a subtree */
4402      stt = info_to_cops_subtree(tvb,st,n,offset,"Downstream Service");
4403      offset += 4;
4404
4405      /* Envelope */
4406      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
4407      offset += 1;
4408
4409      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
4410      offset += 3;
4411
4412      /* Authorized Envelope */
4413      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Authorized Envelope");
4414      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4415
4416      /* Traffic Priority */
4417      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4418      offset += 1;
4419
4420      /* Downstream Resequencing */
4421      info_to_display(tvb,object_tree,offset,1,"Downstream Resequencing",NULL,FMT_HEX,&hf_cops_pcmm_down_resequencing);
4422      offset += 1;
4423
4424      proto_tree_add_text(object_tree, tvb, offset, 2, "Reserved");
4425      offset += 2;
4426
4427      /* Maximum Sustained Traffic Rate */
4428      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4429      offset += 4;
4430
4431      /* Maximum Traffic Burst */
4432      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4433      offset += 4;
4434
4435      /* Minimum Reserved Traffic Rate */
4436      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4437      offset += 4;
4438
4439      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4440      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4441      offset += 2;
4442
4443      /* Reserved */
4444      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4445      offset += 2;
4446
4447      /* Maximum Downstream Latency */
4448      info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
4449      offset += 4;
4450
4451      /* Downstream Peak Traffic Rate */
4452      info_to_display(tvb,object_tree,offset,4,"Downstream Peak Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_down_peak_traffic_rate);
4453      offset += 4;
4454
4455      /* Required Attribute Mask */
4456      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4457      offset += 4;
4458
4459      /* Forbidden Attribute Mask */
4460      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4461      offset += 4;
4462
4463      if (i05) {
4464        /* Attribute Aggregation Rule Mask */
4465        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4466        offset += 4;
4467      }
4468
4469      if (n < 56) return;
4470
4471      /* Reserved Envelope */
4472      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Reserved Envelope");
4473      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4474
4475      /* Traffic Priority */
4476      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4477      offset += 1;
4478
4479      /* Downstream Resequencing */
4480          info_to_display(tvb,object_tree,offset,1,"Downstream Resequencing",NULL,FMT_HEX,&hf_cops_pcmm_down_resequencing);
4481          offset += 1;
4482
4483      proto_tree_add_text(object_tree, tvb, offset, 2, "Reserved");
4484      offset += 2;
4485
4486      /* Maximum Sustained Traffic Rate */
4487      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4488      offset += 4;
4489
4490      /* Maximum Traffic Burst */
4491      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4492      offset += 4;
4493
4494      /* Minimum Reserved Traffic Rate */
4495      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4496      offset += 4;
4497
4498      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4499      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4500      offset += 2;
4501
4502      /* Reserved */
4503      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4504      offset += 2;
4505
4506      /* Maximum Downstream Latency */
4507      info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
4508      offset += 4;
4509
4510      /* Downstream Peak Traffic Rate */
4511      info_to_display(tvb,object_tree,offset,4,"Downstream Peak Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_down_peak_traffic_rate);
4512      offset += 4;
4513
4514      /* Required Attribute Mask */
4515      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4516      offset += 4;
4517
4518      /* Forbidden Attribute Mask */
4519      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4520      offset += 4;
4521
4522      if (i05) {
4523        /* Attribute Aggregation Rule Mask */
4524        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4525        offset += 4;
4526      }
4527
4528      if (n < 80) return;
4529
4530      /* Committed Envelope */
4531      ti = proto_tree_add_text(stt, tvb, offset, i05 ? 40 : 36, "Committed Envelope");
4532      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4533
4534      /* Traffic Priority */
4535      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4536      offset += 1;
4537
4538      /* Downstream Resequencing */
4539          info_to_display(tvb,object_tree,offset,1,"Downstream Resequencing",NULL,FMT_HEX,&hf_cops_pcmm_down_resequencing);
4540          offset += 1;
4541
4542      proto_tree_add_text(object_tree, tvb, offset, 2, "Reserved");
4543      offset += 2;
4544
4545      /* Maximum Sustained Traffic Rate */
4546      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4547      offset += 4;
4548
4549      /* Maximum Traffic Burst */
4550      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4551      offset += 4;
4552
4553      /* Minimum Reserved Traffic Rate */
4554      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4555      offset += 4;
4556
4557      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4558      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4559      offset += 2;
4560
4561      /* Reserved */
4562      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4563      offset += 2;
4564
4565      /* Maximum Downstream Latency */
4566      info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
4567      offset += 4;
4568
4569      /* Downstream Peak Traffic Rate */
4570      info_to_display(tvb,object_tree,offset,4,"Downstream Peak Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_down_peak_traffic_rate);
4571      offset += 4;
4572
4573      /* Required Attribute Mask */
4574      info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
4575      offset += 4;
4576
4577      /* Forbidden Attribute Mask */
4578      info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
4579      offset += 4;
4580
4581      if (i05) {
4582        /* Attribute Aggregation Rule Mask */
4583        info_to_display(tvb,object_tree,offset,4,"Attribute Aggregation Rule Mask",NULL,FMT_DEC,&hf_cops_pcmm_att_aggr_rule_mask);
4584        offset += 4;
4585      }
4586 }
4587
4588 /* Cops - Section : Upstream Drop */
4589 static void
4590 cops_upstream_drop_i04(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
4591      proto_tree *stt;
4592
4593      /* Create a subtree */
4594      stt = info_to_cops_subtree(tvb,st,n,offset,"Upstream Drop");
4595      offset += 4;
4596
4597      /* Envelope */
4598      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
4599      offset += 1;
4600
4601      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
4602      offset += 3;
4603 }
4604
4605 /* END PCMM I04 */
4606
4607 /* Cops - Section : Best Effort Service */
4608 static void
4609 cops_best_effort_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
4610      proto_item *ti;
4611      proto_tree *stt, *object_tree;
4612
4613      /* Create a subtree */
4614      stt = info_to_cops_subtree(tvb,st,n,offset,"Best Effort Service");
4615      offset += 4;
4616
4617      /* Envelope */
4618      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
4619      offset += 1;
4620
4621      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
4622      offset += 3;
4623
4624      /* Authorized Envelope */
4625      ti = proto_tree_add_text(stt, tvb, offset, 24, "Authorized Envelope");
4626      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4627
4628      /* Traffic Priority */
4629      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4630      offset += 1;
4631
4632      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
4633      offset += 3;
4634
4635      /* Request Transmission Policy */
4636      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4637      offset += 4;
4638
4639      /* Maximum Sustained Traffic Rate */
4640      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4641      offset += 4;
4642
4643      /* Maximum Traffic Burst */
4644      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4645      offset += 4;
4646
4647      /* Minimum Reserved Traffic Rate */
4648      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4649      offset += 4;
4650
4651      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4652      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4653      offset += 2;
4654
4655      /* Reserved */
4656      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4657      offset += 2;
4658
4659      if (n < 56) return;
4660
4661      /* Reserved Envelope */
4662      ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
4663      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4664
4665      /* Traffic Priority */
4666      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4667      offset += 1;
4668
4669      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
4670      offset += 3;
4671
4672      /* Request Transmission Policy */
4673      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4674      offset += 4;
4675
4676      /* Maximum Sustained Traffic Rate */
4677      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4678      offset += 4;
4679
4680      /* Maximum Traffic Burst */
4681      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4682      offset += 4;
4683
4684      /* Minimum Reserved Traffic Rate */
4685      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4686      offset += 4;
4687
4688      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4689      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4690      offset += 2;
4691
4692      /* Reserved */
4693      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4694      offset += 2;
4695
4696      if (n < 80) return;
4697
4698      /* Committed Envelope */
4699      ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
4700      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4701
4702      /* Traffic Priority */
4703      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4704      offset += 1;
4705
4706      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
4707      offset += 3;
4708
4709      /* Request Transmission Policy */
4710      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4711      offset += 4;
4712
4713      /* Maximum Sustained Traffic Rate */
4714      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4715      offset += 4;
4716
4717      /* Maximum Traffic Burst */
4718      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4719      offset += 4;
4720
4721      /* Minimum Reserved Traffic Rate */
4722      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4723      offset += 4;
4724
4725      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4726      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4727      offset += 2;
4728
4729      /* Reserved */
4730      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4731      offset += 2;
4732 }
4733
4734 /* Cops - Section : Non-Real-Time Polling Service */
4735 static void
4736 cops_non_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
4737      proto_item *ti;
4738      proto_tree *stt, *object_tree;
4739
4740      /* Create a subtree */
4741      stt = info_to_cops_subtree(tvb,st,n,offset,"Non-Real-Time Polling Service");
4742      offset += 4;
4743
4744      /* Envelope */
4745      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
4746      offset += 1;
4747
4748      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
4749      offset += 3;
4750
4751      /* Authorized Envelope */
4752      ti = proto_tree_add_text(stt, tvb, offset, 28, "Authorized Envelope");
4753      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4754
4755      /* Traffic Priority */
4756      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4757      offset += 1;
4758
4759      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
4760      offset += 3;
4761
4762      /* Request Transmission Policy */
4763      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4764      offset += 4;
4765
4766      /* Maximum Sustained Traffic Rate */
4767      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4768      offset += 4;
4769
4770      /* Maximum Traffic Burst */
4771      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4772      offset += 4;
4773
4774      /* Minimum Reserved Traffic Rate */
4775      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4776      offset += 4;
4777
4778      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4779      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4780      offset += 2;
4781
4782      /* Reserved */
4783      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4784      offset += 2;
4785
4786      /* Nominal Polling Interval */
4787      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4788      offset += 4;
4789
4790      if (n < 64) return;
4791
4792      /* Reserved Envelope */
4793      ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
4794      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4795
4796      /* Traffic Priority */
4797      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4798      offset += 1;
4799
4800      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
4801      offset += 3;
4802
4803      /* Request Transmission Policy */
4804      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4805      offset += 4;
4806
4807      /* Maximum Sustained Traffic Rate */
4808      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4809      offset += 4;
4810
4811      /* Maximum Traffic Burst */
4812      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4813      offset += 4;
4814
4815      /* Minimum Reserved Traffic Rate */
4816      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4817      offset += 4;
4818
4819      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4820      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4821      offset += 2;
4822
4823      /* Reserved */
4824      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4825      offset += 2;
4826
4827      /* Nominal Polling Interval */
4828      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4829      offset += 4;
4830
4831      if (n < 92) return;
4832
4833      /* Committed Envelope */
4834      ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
4835      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4836
4837      /* Traffic Priority */
4838      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
4839      offset += 1;
4840
4841      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
4842      offset += 3;
4843
4844      /* Request Transmission Policy */
4845      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4846      offset += 4;
4847
4848      /* Maximum Sustained Traffic Rate */
4849      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4850      offset += 4;
4851
4852      /* Maximum Traffic Burst */
4853      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4854      offset += 4;
4855
4856      /* Minimum Reserved Traffic Rate */
4857      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4858      offset += 4;
4859
4860      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4861      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4862      offset += 2;
4863
4864      /* Reserved */
4865      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4866      offset += 2;
4867
4868      /* Nominal Polling Interval */
4869      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4870      offset += 4;
4871 }
4872
4873 /* Cops - Section : Real-Time Polling Service */
4874 static void
4875 cops_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
4876      proto_item *ti;
4877      proto_tree *stt, *object_tree;
4878
4879      /* Create a subtree */
4880      stt = info_to_cops_subtree(tvb,st,n,offset,"Real-Time Polling Service");
4881      offset += 4;
4882
4883      /* Envelope */
4884      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
4885      offset += 1;
4886
4887      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
4888      offset += 3;
4889
4890      /* Authorized Envelope */
4891      ti = proto_tree_add_text(stt, tvb, offset, 28, "Authorized Envelope");
4892      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4893
4894      /* Request Transmission Policy */
4895      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4896      offset += 4;
4897
4898      /* Maximum Sustained Traffic Rate */
4899      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4900      offset += 4;
4901
4902      /* Maximum Traffic Burst */
4903      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4904      offset += 4;
4905
4906      /* Minimum Reserved Traffic Rate */
4907      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4908      offset += 4;
4909
4910      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4911      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4912      offset += 2;
4913
4914      /* Reserved */
4915      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4916      offset += 2;
4917
4918      /* Nominal Polling Interval */
4919      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4920      offset += 4;
4921
4922      /* Tolerated Poll Jitter */
4923      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
4924      offset += 4;
4925
4926      if (n < 64) return;
4927
4928      /* Reserved Envelope */
4929      ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
4930      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4931
4932      /* Request Transmission Policy */
4933      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4934      offset += 4;
4935
4936      /* Maximum Sustained Traffic Rate */
4937      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4938      offset += 4;
4939
4940      /* Maximum Traffic Burst */
4941      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4942      offset += 4;
4943
4944      /* Minimum Reserved Traffic Rate */
4945      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4946      offset += 4;
4947
4948      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4949      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4950      offset += 2;
4951
4952      /* Reserved */
4953      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4954      offset += 2;
4955
4956      /* Nominal Polling Interval */
4957      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4958      offset += 4;
4959
4960      /* Tolerated Poll Jitter */
4961      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
4962      offset += 4;
4963
4964      if (n < 92) return;
4965
4966      /* Committed Envelope */
4967      ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
4968      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
4969
4970      /* Request Transmission Policy */
4971      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
4972      offset += 4;
4973
4974      /* Maximum Sustained Traffic Rate */
4975      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
4976      offset += 4;
4977
4978      /* Maximum Traffic Burst */
4979      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
4980      offset += 4;
4981
4982      /* Minimum Reserved Traffic Rate */
4983      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
4984      offset += 4;
4985
4986      /* Assumed Minimum Reserved Traffic Rate Packet Size */
4987      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
4988      offset += 2;
4989
4990      /* Reserved */
4991      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
4992      offset += 2;
4993
4994      /* Nominal Polling Interval */
4995      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
4996      offset += 4;
4997
4998      /* Tolerated Poll Jitter */
4999      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
5000      offset += 4;
5001 }
5002
5003 /* Cops - Section : Unsolicited Grant Service */
5004 static void
5005 cops_unsolicited_grant_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5006      proto_item *ti;
5007      proto_tree *stt, *object_tree;
5008
5009      /* Create a subtree */
5010      stt = info_to_cops_subtree(tvb,st,n,offset,"Unsolicited Grant Service");
5011      offset += 4;
5012
5013      /* Envelope */
5014      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
5015      offset += 1;
5016
5017      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
5018      offset += 3;
5019
5020      /* Authorized Envelope */
5021      ti = proto_tree_add_text(stt, tvb, offset, 16, "Authorized Envelope");
5022      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5023
5024      /* Request Transmission Policy */
5025      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
5026      offset += 4;
5027
5028      /* Unsolicited Grant Size */
5029      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
5030      offset += 2;
5031
5032      /* Grants Per Interval */
5033      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
5034      offset += 1;
5035
5036      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
5037      offset += 1;
5038
5039      /* Nominal Grant Interval */
5040      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
5041      offset += 4;
5042
5043      /* Tolerated Grant Jitter */
5044      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
5045      offset += 4;
5046
5047      if (n < 40) return;
5048
5049      /* Reserved Envelope */
5050      ti = proto_tree_add_text(stt, tvb, offset, 16, "Reserved Envelope");
5051      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5052
5053      /* Request Transmission Policy */
5054      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
5055      offset += 4;
5056
5057      /* Unsolicited Grant Size */
5058      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
5059      offset += 2;
5060
5061      /* Grants Per Interval */
5062      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
5063      offset += 1;
5064
5065      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
5066      offset += 1;
5067
5068      /* Nominal Grant Interval */
5069      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
5070      offset += 4;
5071
5072      /* Tolerated Grant Jitter */
5073      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
5074      offset += 4;
5075
5076      if (n < 56) return;
5077
5078      /* Committed Envelope */
5079      ti = proto_tree_add_text(stt, tvb, offset, 16, "Committed Envelope");
5080      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5081
5082      /* Request Transmission Policy */
5083      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
5084      offset += 4;
5085
5086      /* Unsolicited Grant Size */
5087      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
5088      offset += 2;
5089
5090      /* Grants Per Interval */
5091      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
5092      offset += 1;
5093
5094      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
5095      offset += 1;
5096
5097      /* Nominal Grant Interval */
5098      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
5099      offset += 4;
5100
5101      /* Tolerated Grant Jitter */
5102      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
5103      offset += 4;
5104 }
5105
5106 /* Cops - Section : Unsolicited Grant Service with Activity Detection */
5107 static void
5108 cops_ugs_with_activity_detection(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5109      proto_item *ti;
5110      proto_tree *stt, *object_tree;
5111
5112      /* Create a subtree */
5113      stt = info_to_cops_subtree(tvb,st,n,offset,"Unsolicited Grant Service with Activity Detection");
5114      offset += 4;
5115
5116      /* Envelope */
5117      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
5118      offset += 1;
5119
5120      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
5121      offset += 3;
5122
5123      /* Authorized Envelope */
5124      ti = proto_tree_add_text(stt, tvb, offset, 24, "Authorized Envelope");
5125      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5126
5127      /* Request Transmission Policy */
5128      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
5129      offset += 4;
5130
5131      /* Unsolicited Grant Size */
5132      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
5133      offset += 2;
5134
5135      /* Grants Per Interval */
5136      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
5137      offset += 1;
5138
5139      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
5140      offset += 1;
5141
5142      /* Nominal Grant Interval */
5143      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
5144      offset += 4;
5145
5146      /* Tolerated Grant Jitter */
5147      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
5148      offset += 4;
5149
5150      /* Nominal Polling Interval */
5151      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
5152      offset += 4;
5153
5154      /* Tolerated Poll Jitter */
5155      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
5156      offset += 4;
5157
5158      if (n < 56) return;
5159
5160      /* Reserved Envelope */
5161      ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
5162      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5163
5164      /* Request Transmission Policy */
5165      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
5166      offset += 4;
5167
5168      /* Unsolicited Grant Size */
5169      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
5170      offset += 2;
5171
5172      /* Grants Per Interval */
5173      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
5174      offset += 1;
5175
5176      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
5177      offset += 1;
5178
5179      /* Nominal Grant Interval */
5180      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
5181      offset += 4;
5182
5183      /* Tolerated Grant Jitter */
5184      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
5185      offset += 4;
5186
5187      /* Nominal Polling Interval */
5188      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
5189      offset += 4;
5190
5191      /* Tolerated Poll Jitter */
5192      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
5193      offset += 4;
5194
5195      if (n < 80) return;
5196
5197      /* Committed Envelope */
5198      ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
5199      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5200
5201      /* Request Transmission Policy */
5202      decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
5203      offset += 4;
5204
5205      /* Unsolicited Grant Size */
5206      info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
5207      offset += 2;
5208
5209      /* Grants Per Interval */
5210      info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
5211      offset += 1;
5212
5213      proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
5214      offset += 1;
5215
5216      /* Nominal Grant Interval */
5217      info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
5218      offset += 4;
5219
5220      /* Tolerated Grant Jitter */
5221      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
5222      offset += 4;
5223
5224      /* Nominal Polling Interval */
5225      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
5226      offset += 4;
5227
5228      /* Tolerated Poll Jitter */
5229      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
5230      offset += 4;
5231 }
5232
5233 /* Cops - Section : Downstream Service */
5234 static void
5235 cops_downstream_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5236      proto_item *ti;
5237      proto_tree *stt, *object_tree;
5238
5239      /* Create a subtree */
5240      stt = info_to_cops_subtree(tvb,st,n,offset,"Downstream Service");
5241      offset += 4;
5242
5243      /* Envelope */
5244      info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
5245      offset += 1;
5246
5247      proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
5248      offset += 3;
5249
5250      /* Authorized Envelope */
5251      ti = proto_tree_add_text(stt, tvb, offset, 24, "Authorized Envelope");
5252      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5253
5254      /* Traffic Priority */
5255      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
5256      offset += 1;
5257
5258      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
5259      offset += 3;
5260
5261      /* Maximum Sustained Traffic Rate */
5262      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
5263      offset += 4;
5264
5265      /* Maximum Traffic Burst */
5266      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
5267      offset += 4;
5268
5269      /* Minimum Reserved Traffic Rate */
5270      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
5271      offset += 4;
5272
5273      /* Assumed Minimum Reserved Traffic Rate Packet Size */
5274      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
5275      offset += 2;
5276
5277      /* Reserved */
5278      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
5279      offset += 2;
5280
5281      /* Maximum Downstream Latency */
5282      info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
5283      offset += 4;
5284
5285      if (n < 56) return;
5286
5287      /* Reserved Envelope */
5288      ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
5289      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5290
5291      /* Traffic Priority */
5292      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
5293      offset += 1;
5294
5295      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
5296      offset += 3;
5297
5298      /* Maximum Sustained Traffic Rate */
5299      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
5300      offset += 4;
5301
5302      /* Maximum Traffic Burst */
5303      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
5304      offset += 4;
5305
5306      /* Minimum Reserved Traffic Rate */
5307      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
5308      offset += 4;
5309
5310      /* Assumed Minimum Reserved Traffic Rate Packet Size */
5311      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
5312      offset += 2;
5313
5314      /* Reserved */
5315      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
5316      offset += 2;
5317
5318      /* Maximum Downstream Latency */
5319      info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
5320      offset += 4;
5321
5322      if (n < 80) return;
5323
5324      /* Committed Envelope */
5325      ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
5326      object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
5327
5328      /* Traffic Priority */
5329      info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
5330      offset += 1;
5331
5332      proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
5333      offset += 3;
5334
5335      /* Maximum Sustained Traffic Rate */
5336      info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
5337      offset += 4;
5338
5339      /* Maximum Traffic Burst */
5340      info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
5341      offset += 4;
5342
5343      /* Minimum Reserved Traffic Rate */
5344      info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
5345      offset += 4;
5346
5347      /* Assumed Minimum Reserved Traffic Rate Packet Size */
5348      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
5349      offset += 2;
5350
5351      /* Reserved */
5352      info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
5353      offset += 2;
5354
5355      /* Maximum Downstream Latency */
5356      info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
5357      offset += 4;
5358 }
5359
5360 /* Cops - Section : PacketCable Multimedia Event Gereration-Info */
5361 static void
5362 cops_mm_event_generation_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5363
5364      proto_tree *stt;
5365      guint8 *bcid_str;
5366
5367      /* Create a subtree */
5368      stt = info_to_cops_subtree(tvb,st,n,offset,"Event Generation Info");
5369      offset += 4;
5370
5371      /* Primary Record Keeping Server IP Address */
5372      info_to_display(tvb,stt,offset,4,"PRKS IP Address", NULL,FMT_IPv4,&hf_cops_pc_prks_ip);
5373      offset += 4;
5374
5375      /* Primary Record Keeping Server IP Port */
5376      info_to_display(tvb,stt,offset,2,"PRKS IP Port",NULL,FMT_DEC,&hf_cops_pc_prks_ip_port);
5377      offset += 2;
5378
5379      /* Reserved */
5380      info_to_display(tvb,stt,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
5381      offset += 2;
5382
5383      /* Secondary Record Keeping Server IP Address */
5384      info_to_display(tvb,stt,offset,4,"SRKS IP Address", NULL,FMT_IPv4,&hf_cops_pc_srks_ip);
5385      offset += 4;
5386
5387      /* Secondary Record Keeping Server IP Port */
5388      info_to_display(tvb,stt,offset,2,"SRKS IP Port",NULL,FMT_DEC,&hf_cops_pc_srks_ip_port);
5389      offset += 2;
5390
5391      /* Reserved */
5392      info_to_display(tvb,stt,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
5393      offset += 2;
5394
5395      /* BCID Timestamp */
5396      info_to_display(tvb,stt,offset,4,"BCID - Timestamp",NULL,FMT_HEX,&hf_cops_pc_bcid_ts);
5397      offset += 4;
5398
5399      /* BCID Element ID */
5400      bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
5401      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Element ID",bcid_str);
5402      offset += 8;
5403
5404      /* BCID Time Zone */
5405      bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
5406      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Time Zone",bcid_str);
5407      offset += 8;
5408
5409      /* BCID Event Counter */
5410      info_to_display(tvb,stt,offset,4,"BCID - Event Counter",NULL,FMT_DEC,&hf_cops_pc_bcid_ev);
5411 }
5412
5413 /* Cops - Section : Volume-Based Usage Limit */
5414 static void
5415 cops_volume_based_usage_limit(tvbuff_t *tvb, proto_tree *st, guint object_len, guint32 offset) {
5416
5417      proto_tree *stt;
5418
5419      /* Create a subtree */
5420      stt = info_to_cops_subtree(tvb,st,object_len,offset,"Volume-Based Usage Limit");
5421      offset += 4;
5422
5423      /* Usage Limit */
5424      proto_tree_add_item(stt, hf_cops_pcmm_volume_based_usage_limit, tvb, offset, 8,
5425             FALSE);
5426 }
5427
5428 /* Cops - Section : Time-Based Usage Limit */
5429 static void
5430 cops_time_based_usage_limit(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5431
5432      proto_tree *stt;
5433
5434      /* Create a subtree */
5435      stt = info_to_cops_subtree(tvb,st,n,offset,"Time-Based Usage Limit");
5436      offset += 4;
5437
5438      /* Time Limit */
5439      info_to_display(tvb,stt,offset,4,"Time Limit", NULL,FMT_DEC,&hf_cops_pcmm_time_based_usage_limit);
5440      offset += 4;
5441 }
5442
5443 /* Cops - Section : Opaque Data */
5444 static void
5445 cops_opaque_data(tvbuff_t *tvb, proto_tree *st, guint object_len, guint32 offset) {
5446
5447      proto_tree *stt;
5448
5449      /* Create a subtree */
5450      stt = info_to_cops_subtree(tvb,st,object_len,offset,"Opaque Data");
5451      offset += 4;
5452
5453      /* Opaque Data */
5454      proto_tree_add_text(stt, tvb, offset, 8,"Opaque Data");
5455 }
5456
5457 /* Cops - Section : Gate Time Info */
5458 static void
5459 cops_gate_time_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5460
5461      proto_tree *stt;
5462
5463      /* Create a subtree */
5464      stt = info_to_cops_subtree(tvb,st,n,offset,"Gate Time Info");
5465      offset += 4;
5466
5467      /* Gate Time Info */
5468      info_to_display(tvb,stt,offset,4,"Time Committed", NULL,FMT_DEC,&hf_cops_pcmm_gate_time_info);
5469      offset += 4;
5470 }
5471
5472 /* Cops - Section : Gate Usage Info */
5473 static void
5474 cops_gate_usage_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5475
5476      proto_tree *stt;
5477
5478      /* Create a subtree */
5479      stt = info_to_cops_subtree(tvb,st,n,offset,"Gate Usage Info");
5480      offset += 4;
5481
5482      /* Gate Usage Info */
5483      info_to_display(tvb,stt,offset,8,"Octet Count", NULL,FMT_DEC,&hf_cops_pcmm_gate_usage_info);
5484 }
5485
5486 /* Cops - Section : PacketCable error */
5487 static void
5488 cops_packetcable_mm_error(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5489
5490      proto_tree *stt;
5491      guint16 code, subcode;
5492
5493      /* Create a subtree */
5494      stt = info_to_cops_subtree(tvb,st,n,offset,"PacketCable Error");
5495      offset += 4;
5496
5497      code = tvb_get_ntohs(tvb, offset);
5498      proto_tree_add_uint_format(stt, hf_cops_pcmm_packetcable_error_code, tvb, offset, 2, code,
5499             "Error Code: %s (%u)", val_to_str(code, pcmm_packetcable_error_code, "Unknown"),
5500             code);
5501      offset += 2;
5502
5503      subcode = tvb_get_ntohs(tvb, offset);
5504      if (code == 6 || code == 7)
5505             proto_tree_add_uint_format(stt, hf_cops_pcmm_packetcable_error_subcode,
5506                     tvb, offset, 2, code, "Error-Subcode: 0x%02x, S-Num: 0x%02x, S-Type: 0x%02x",
5507                     subcode, subcode >> 8, subcode & 0xf);
5508      else
5509             proto_tree_add_uint_format(stt, hf_cops_pcmm_packetcable_error_subcode,
5510                     tvb, offset, 2, code, "Error-Subcode: 0x%04x", subcode);
5511      offset += 2;
5512 }
5513
5514 /* Cops - Section : Gate State */
5515 static void
5516 cops_gate_state(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5517
5518      proto_tree *stt;
5519
5520      /* Create a subtree */
5521      stt = info_to_cops_subtree(tvb,st,n,offset,"Gate State");
5522      offset += 4;
5523
5524      /* State */
5525      info_to_display(tvb,stt,offset,2,"State",pcmm_gate_state,FMT_DEC,&hf_cops_pcmm_packetcable_gate_state);
5526      offset += 2;
5527
5528      /* Reason */
5529      info_to_display(tvb,stt,offset,2,"Reason",pcmm_gate_state_reason,FMT_DEC,&hf_cops_pcmm_packetcable_gate_state_reason);
5530      offset += 2;
5531 }
5532
5533 /* Cops - Section : Version Info */
5534 static void
5535 cops_version_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5536
5537      proto_tree *stt;
5538
5539      /* Create a subtree */
5540      stt = info_to_cops_subtree(tvb,st,n,offset,"Version Info");
5541      offset += 4;
5542
5543      /* State */
5544      info_to_display(tvb,stt,offset,2,"Major Version Number",NULL,FMT_DEC,&hf_cops_pcmm_packetcable_version_info_major);
5545      offset += 2;
5546
5547      /* Reason */
5548      info_to_display(tvb,stt,offset,2,"Minor Version Number",NULL,FMT_DEC,&hf_cops_pcmm_packetcable_version_info_minor);
5549      offset += 2;
5550 }
5551
5552 /* Cops - Section : PSID */
5553 static void
5554 cops_psid(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5555
5556      proto_tree *stt;
5557
5558      /* Create a subtree */
5559      stt = info_to_cops_subtree(tvb,st,n,offset,"PSID");
5560      offset += 4;
5561
5562      /* PSID */
5563      info_to_display(tvb,stt,offset,4,"PSID", NULL,FMT_DEC,&hf_cops_pcmm_psid);
5564 }
5565
5566 /* Cops - Section : Synch Options */
5567 static void
5568 cops_synch_options(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5569
5570      proto_tree *stt;
5571
5572      /* Create a subtree */
5573      stt = info_to_cops_subtree(tvb,st,n,offset,"Synch Options");
5574      offset += 4;
5575
5576      proto_tree_add_text(stt, tvb, offset, 2, "Reserved");
5577      offset += 2;
5578
5579      /* Report Type */
5580      info_to_display(tvb,stt,offset,1,"Report Type", pcmm_report_type_vals,FMT_DEC,&hf_cops_pcmm_synch_options_report_type);
5581      offset += 1;
5582
5583      /* Sych Type */
5584      info_to_display(tvb,stt,offset,1,"Synch Type", pcmm_synch_type_vals,FMT_DEC,&hf_cops_pcmm_synch_options_synch_type);
5585      offset += 1;
5586 }
5587
5588 /* Cops - Section : Msg Receipt Key */
5589 static void
5590 cops_msg_receipt_key(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5591
5592      proto_tree *stt;
5593
5594      /* Create a subtree */
5595      stt = info_to_cops_subtree(tvb,st,n,offset,"Msg Receipt Key");
5596      offset += 4;
5597
5598      /* Msg Receipt Key */
5599      info_to_display(tvb,stt,offset,4,"Msg Receipt Key", NULL,FMT_HEX,&hf_cops_pcmm_msg_receipt_key);
5600 }
5601
5602 /* Cops - Section : UserID */
5603 static void
5604 cops_userid(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5605
5606      proto_tree *stt;
5607
5608      /* Create a subtree */
5609      stt = info_to_cops_subtree(tvb, st, n, offset, "UserID");
5610      offset += 4;
5611
5612      /* UserID */
5613      info_to_display(tvb, stt, offset, n-4, "UserID", NULL, FMT_STR, &hf_cops_pcmm_userid);
5614 }
5615
5616 /* Cops - Section : SharedResourceID */
5617 static void
5618 cops_sharedresourceid(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
5619
5620      proto_tree *stt;
5621
5622      /* Create a subtree */
5623      stt = info_to_cops_subtree(tvb,st,n,offset,"SharedResourceID");
5624      offset += 4;
5625
5626      /* SharedResourceID */
5627      info_to_display(tvb,stt,offset,4,"SharedResourceID", NULL,FMT_HEX,&hf_cops_pcmm_sharedresourceid);
5628 }
5629
5630 /* PacketCable D-QoS S-Num/S-Type globs */
5631 #define PCDQ_TRANSACTION_ID              0x0101
5632 #define PCDQ_SUBSCRIBER_IDv4             0x0201
5633 #define PCDQ_SUBSCRIBER_IDv6             0x0202
5634 #define PCDQ_GATE_ID                     0x0301
5635 #define PCDQ_ACTIVITY_COUNT              0x0401
5636 #define PCDQ_GATE_SPEC                   0x0501
5637 #define PCDQ_REMOTE_GATE_INFO            0x0601
5638 #define PCDQ_EVENT_GENERATION_INFO       0x0701
5639 #define PCDQ_MEDIA_CONNECTION_EVENT_INFO 0x0801
5640 #define PCDQ_PACKETCABLE_ERROR           0x0901
5641 #define PCDQ_PACKETCABLE_REASON          0x0d01
5642 #define PCDQ_ELECTRONIC_SURVEILLANCE     0x0a01
5643 #define PCDQ_SESSION_DESCRIPTION         0x0b01
5644
5645 /* Analyze the PacketCable objects */
5646 static void
5647 cops_analyze_packetcable_dqos_obj(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 op_code, guint32 offset) {
5648
5649     gint remdata;
5650     guint16 object_len;
5651     guint8 s_num, s_type;
5652     guint16 num_type_glob;
5653
5654     /* Only if this option is enabled by the Gui */
5655     if ( cops_packetcable == FALSE ) {
5656        return;
5657     }
5658
5659     /* Do the remaining client specific objects */
5660     remdata = tvb_length_remaining(tvb, offset);
5661     while (remdata > 4) {
5662
5663        /* In case we have remaining data, then lets try to get this analyzed */
5664        object_len   = tvb_get_ntohs(tvb, offset);
5665        if (object_len < 4) {
5666         proto_tree_add_text(tree, tvb, offset, 2,
5667             "Incorrect PacketCable object length %u < 4", object_len);
5668         return;
5669        }
5670
5671        s_num        = tvb_get_guint8(tvb, offset + 2);
5672        s_type       = tvb_get_guint8(tvb, offset + 3);
5673
5674        /* Glom the s_num and s_type together to make switching easier */
5675        num_type_glob = s_num << 8 | s_type;
5676
5677        /* Perform the appropriate functions */
5678        switch (num_type_glob){
5679         case PCDQ_TRANSACTION_ID:
5680                cops_transaction_id(tvb, pinfo, tree, op_code, object_len, offset);
5681                break;
5682         case PCDQ_SUBSCRIBER_IDv4:
5683                cops_subscriber_id_v4(tvb, tree, object_len, offset);
5684                break;
5685         case PCDQ_SUBSCRIBER_IDv6:
5686                cops_subscriber_id_v6(tvb, tree, object_len, offset);
5687                break;
5688         case PCDQ_GATE_ID:
5689                cops_gate_id(tvb, tree, object_len, offset);
5690                break;
5691         case PCDQ_ACTIVITY_COUNT:
5692                cops_activity_count(tvb, tree, object_len, offset);
5693                break;
5694         case PCDQ_GATE_SPEC:
5695                cops_gate_specs(tvb, tree, object_len, offset);
5696                break;
5697         case PCDQ_REMOTE_GATE_INFO:
5698                cops_remote_gate_info(tvb, tree, object_len, offset);
5699                break;
5700         case PCDQ_EVENT_GENERATION_INFO:
5701                cops_event_generation_info(tvb, tree, object_len, offset);
5702                break;
5703         case PCDQ_PACKETCABLE_ERROR:
5704                cops_packetcable_error(tvb, tree, object_len, offset);
5705                break;
5706         case PCDQ_ELECTRONIC_SURVEILLANCE:
5707                cops_surveillance_parameters(tvb, tree, object_len, offset);
5708                break;
5709         case PCDQ_PACKETCABLE_REASON:
5710                cops_packetcable_reason(tvb, tree, object_len, offset);
5711                break;
5712        }
5713
5714        /* Tune offset */
5715        offset += object_len;
5716
5717        /* See what we can still get from the buffer */
5718        remdata = tvb_length_remaining(tvb, offset);
5719     }
5720 }
5721
5722 /* XXX - This duplicates code in the DOCSIS dissector. */
5723 static void
5724 decode_docsis_request_transmission_policy(tvbuff_t *tvb, guint32 offset, proto_tree *tree, gint hf) {
5725         proto_tree *drtp_tree;
5726         proto_item *item;
5727         guint32 policy = tvb_get_ntohl(tvb, offset);
5728         int i;
5729         char bit_fld[48];
5730         static const value_string drtp_vals[] = {
5731                 { 1 << 0, "The Service Flow MUST NOT use \"all CMs\" broadcast request opportunities" },
5732                 { 1 << 1, "The Service Flow MUST NOT use Priority Request multicast request opportunities" },
5733                 { 1 << 2, "The Service Flow MUST NOT use Request/Data opportunities for Requests" },
5734                 { 1 << 3, "The Service Flow MUST NOT use Request/Data opportunities for Data" },
5735                 { 1 << 4, "The Service Flow MUST NOT piggyback requests with data" },
5736                 { 1 << 5, "The Service Flow MUST NOT concatenate data" },
5737                 { 1 << 6, "The Service Flow MUST NOT fragment data" },
5738                 { 1 << 7, "The Service Flow MUST NOT suppress payload headers" },
5739                 { 1 << 8, "The Service Flow MUST drop packets that do not fit in the Unsolicited Grant Size" },
5740                 { 0, NULL }
5741         };
5742
5743         item = proto_tree_add_item (tree, hf, tvb, offset, 4, FALSE);
5744         drtp_tree = proto_item_add_subtree(item, ett_docsis_request_transmission_policy);
5745         for (i = 0 ; i <= 8; i++) {
5746                 if (policy & drtp_vals[i].value) {
5747                         decode_bitfield_value(bit_fld, policy, drtp_vals[i].value, 32);
5748                         proto_tree_add_text(drtp_tree, tvb, offset, 4, "%s%s",
5749                                 bit_fld, drtp_vals[i].strptr);
5750                 }
5751         }
5752 }
5753
5754
5755 #define PCMM_TRANSACTION_ID                0x0101
5756 #define PCMM_AMID                          0x0201
5757 #define PCMM_SUBSCRIBER_ID                 0x0301
5758 #define PCMM_SUBSCRIBER_ID_V6              0x0302
5759 #define PCMM_GATE_ID                       0x0401
5760 #define PCMM_GATE_SPEC                     0x0501
5761 #define PCMM_CLASSIFIER                    0x0601
5762 #define PCMM_EXTENDED_CLASSIFIER           0x0602
5763 #define PCMM_IPV6_CLASSIFIER               0x0603
5764 #define PCMM_FLOW_SPEC                     0x0701
5765 #define PCMM_DOCSIS_SERVICE_CLASS_NAME     0x0702
5766 #define PCMM_BEST_EFFORT_SERVICE           0x0703
5767 #define PCMM_NON_REAL_TIME_POLLING_SERVICE 0x0704
5768 #define PCMM_REAL_TIME_POLLING_SERVICE     0x0705
5769 #define PCMM_UNSOLICITED_GRANT_SERVICE     0x0706
5770 #define PCMM_UGS_WITH_ACTIVITY_DETECTION   0x0707
5771 #define PCMM_DOWNSTREAM_SERVICE            0x0708
5772 #define PCMM_UPSTREAM_DROP                 0x0709
5773 #define PCMM_EVENT_GENERATION_INFO         0x0801
5774 #define PCMM_VOLUME_BASED_USAGE_LIMIT      0x0901
5775 #define PCMM_TIME_BASED_USAGE_LIMIT        0x0a01
5776 #define PCMM_OPAQUE_DATA                   0x0b01
5777 #define PCMM_GATE_TIME_INFO                0x0c01
5778 #define PCMM_GATE_USAGE_INFO               0x0d01
5779 #define PCMM_PACKETCABLE_ERROR             0x0e01
5780 #define PCMM_GATE_STATE                    0x0f01
5781 #define PCMM_VERSION_INFO                  0x1001
5782 #define PCMM_PSID                          0x1101
5783 #define PCMM_SYNCH_OPTIONS                 0x1201
5784 #define PCMM_MSG_RECEIPT_KEY               0x1301
5785 #define PCMM_USERID                        0x1501
5786 #define PCMM_SHAREDRESOURCEID              0x1601
5787
5788
5789 static void
5790 cops_analyze_packetcable_mm_obj(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 op_code, guint32 offset) {
5791
5792     guint16 object_len;
5793     guint8 s_num, s_type;
5794     guint16 num_type_glob;
5795
5796     /* Only if this option is enabled by the Gui */
5797     if ( cops_packetcable == FALSE ) {
5798        return;
5799     }
5800
5801     /* Do the remaining client specific objects */
5802     while (tvb_reported_length_remaining(tvb, offset) > 4) {
5803
5804        /* In case we have remaining data, then lets try to get this analyzed */
5805        object_len   = tvb_get_ntohs(tvb, offset);
5806        if (object_len < 4) {
5807         proto_tree_add_text(tree, tvb, offset, 2,
5808             "Incorrect PacketCable object length %u < 4", object_len);
5809         return;
5810        }
5811
5812        s_num        = tvb_get_guint8(tvb, offset + 2);
5813        s_type       = tvb_get_guint8(tvb, offset + 3);
5814
5815        /* Glom the s_num and s_type together to make switching easier */
5816        num_type_glob = s_num << 8 | s_type;
5817
5818        /* Perform the appropriate functions */
5819        switch (num_type_glob){
5820         case PCMM_TRANSACTION_ID:
5821                cops_mm_transaction_id(tvb, pinfo, tree, op_code, object_len, offset);
5822                break;
5823         case PCMM_AMID:
5824                cops_amid(tvb, tree, object_len, offset);
5825                break;
5826         case PCMM_SUBSCRIBER_ID:
5827                cops_subscriber_id_v4(tvb, tree, object_len, offset);
5828                break;
5829         case PCMM_SUBSCRIBER_ID_V6:
5830                cops_subscriber_id_v6(tvb, tree, object_len, offset);
5831                break;
5832         case PCMM_GATE_ID:
5833                cops_gate_id(tvb, tree, object_len, offset);
5834                break;
5835         case PCMM_GATE_SPEC:
5836                cops_mm_gate_spec(tvb, tree, object_len, offset);
5837                break;
5838         case PCMM_CLASSIFIER:
5839                cops_classifier(tvb, tree, object_len, offset, FALSE);
5840                break;
5841         case PCMM_EXTENDED_CLASSIFIER:
5842                cops_classifier(tvb, tree, object_len, offset, TRUE);
5843                break;
5844         case PCMM_IPV6_CLASSIFIER:
5845                    cops_ipv6_classifier(tvb, tree, object_len, offset);
5846                            break;
5847         case PCMM_FLOW_SPEC:
5848                cops_flow_spec(tvb, tree, object_len, offset);
5849                break;
5850         case PCMM_DOCSIS_SERVICE_CLASS_NAME:
5851                cops_docsis_service_class_name(tvb, tree, object_len, offset);
5852                break;
5853         case PCMM_BEST_EFFORT_SERVICE:
5854                        if (object_len == 44 || object_len == 80 || object_len == 116)
5855                            cops_best_effort_service_i04_i05(tvb, tree, object_len, offset, TRUE);
5856                        else if (object_len == 40 || object_len == 72 || object_len == 104)
5857                            cops_best_effort_service_i04_i05(tvb, tree, object_len, offset, FALSE);
5858                        else
5859                            cops_best_effort_service(tvb, tree, object_len, offset);
5860                        break;
5861         case PCMM_NON_REAL_TIME_POLLING_SERVICE:
5862                    if (object_len == 48 || object_len == 88 || object_len == 128)
5863                            cops_non_real_time_polling_service_i04_i05(tvb, tree, object_len, offset, TRUE);
5864                    else if (object_len == 44 || object_len == 80 || object_len == 116)
5865                            cops_non_real_time_polling_service_i04_i05(tvb, tree, object_len, offset, FALSE);
5866                    else
5867                            cops_non_real_time_polling_service(tvb, tree, object_len, offset);
5868                break;
5869         case PCMM_REAL_TIME_POLLING_SERVICE:
5870                    if (object_len == 48 || object_len == 88 || object_len == 128)
5871                            cops_real_time_polling_service_i04_i05(tvb, tree, object_len, offset, TRUE);
5872                    else if (object_len == 44 || object_len == 80 || object_len == 116)
5873                            cops_real_time_polling_service_i04_i05(tvb, tree, object_len, offset, FALSE);
5874                    else
5875                            cops_real_time_polling_service(tvb, tree, object_len, offset);
5876                break;
5877         case PCMM_UNSOLICITED_GRANT_SERVICE:
5878                    if (object_len == 36 || object_len == 64 || object_len == 92)
5879                           cops_unsolicited_grant_service_i04_i05(tvb, tree, object_len, offset, TRUE);
5880                    else if (object_len == 32 || object_len == 56 || object_len == 80)
5881                           cops_unsolicited_grant_service_i04_i05(tvb, tree, object_len, offset, FALSE);
5882                    else
5883                            cops_unsolicited_grant_service(tvb, tree, object_len, offset);
5884                    break;
5885         case PCMM_UGS_WITH_ACTIVITY_DETECTION:
5886                    if (object_len == 44 || object_len == 80 || object_len == 116)
5887                           cops_ugs_with_activity_detection_i04_i05(tvb, tree, object_len, offset, TRUE);
5888                    else if (object_len == 40 || object_len == 72 || object_len == 104)
5889                           cops_ugs_with_activity_detection_i04_i05(tvb, tree, object_len, offset, FALSE);
5890                    else
5891                            cops_ugs_with_activity_detection(tvb, tree, object_len, offset);
5892                    break;
5893         case PCMM_DOWNSTREAM_SERVICE:
5894                    if (object_len == 48 || object_len == 88 || object_len == 128)
5895                            cops_downstream_service_i04_i05(tvb, tree, object_len, offset, TRUE);
5896                    else if (object_len == 40 || object_len == 72 || object_len == 104)
5897                            cops_downstream_service_i04_i05(tvb, tree, object_len, offset, FALSE);
5898                    else
5899                            cops_downstream_service(tvb, tree, object_len, offset);
5900                    break;
5901         case PCMM_UPSTREAM_DROP:
5902                    cops_upstream_drop_i04(tvb, tree, object_len, offset);
5903                    break;
5904         case PCMM_EVENT_GENERATION_INFO:
5905                cops_mm_event_generation_info(tvb, tree, object_len, offset);
5906                break;
5907         case PCMM_VOLUME_BASED_USAGE_LIMIT:
5908                cops_volume_based_usage_limit(tvb, tree, object_len, offset);
5909                break;
5910         case PCMM_TIME_BASED_USAGE_LIMIT:
5911                cops_time_based_usage_limit(tvb, tree, object_len, offset);
5912                break;
5913         case PCMM_OPAQUE_DATA:
5914                cops_opaque_data(tvb, tree, object_len, offset);
5915                break;
5916         case PCMM_GATE_TIME_INFO:
5917                cops_gate_time_info(tvb, tree, object_len, offset);
5918                break;
5919         case PCMM_GATE_USAGE_INFO:
5920                cops_gate_usage_info(tvb, tree, object_len, offset);
5921                break;
5922         case PCMM_PACKETCABLE_ERROR:
5923                cops_packetcable_mm_error(tvb, tree, object_len, offset);
5924                break;
5925         case PCMM_GATE_STATE:
5926                cops_gate_state(tvb, tree, object_len, offset);
5927                break;
5928         case PCMM_VERSION_INFO:
5929                cops_version_info(tvb, tree, object_len, offset);
5930                break;
5931         case PCMM_PSID:
5932                cops_psid(tvb, tree, object_len, offset);
5933                break;
5934         case PCMM_SYNCH_OPTIONS:
5935                cops_synch_options(tvb, tree, object_len, offset);
5936                break;
5937         case PCMM_MSG_RECEIPT_KEY:
5938                cops_msg_receipt_key(tvb, tree, object_len, offset);
5939                break;
5940         case PCMM_USERID:
5941                cops_userid(tvb, tree, object_len, offset);
5942                break;
5943         case PCMM_SHAREDRESOURCEID:
5944                cops_sharedresourceid(tvb, tree, object_len, offset);
5945                break;
5946
5947        }
5948
5949        /* Tune offset */
5950        offset += object_len;
5951     }
5952 }
5953
5954
5955 /* End of PacketCable Addition */