Use some default true_false_string's.
[metze/wireshark/wip.git] / epan / dissectors / packet-slowprotocols.c
1 /* packet-slowprotocols.c
2  * Routines for EtherType (0x8809) Slow Protocols disassembly.
3  *
4  * $Id$
5  *
6  * Copyright 2002 Steve Housley <steve_housley@3com.com>
7  * Copyright 2005 Dominique Bastien <dbastien@accedian.com>
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <glib.h>
35 #include <epan/packet.h>
36 #include <epan/etypes.h>
37 #include <epan/llcsaps.h>
38 #include <epan/ppptypes.h>
39 #include <epan/addr_resolv.h>
40
41 /* General declarations */
42
43 #define SLOW_PROTO_SUBTYPE              0
44
45 #define LACP_SUBTYPE                    0x1
46 #define MARKER_SUBTYPE                  0x2
47 #define OAM_SUBTYPE                     0x3
48
49
50 /* Offsets of fields within a LACPDU */
51
52 #define LACPDU_VERSION_NUMBER           1
53
54 #define LACPDU_ACTOR_TYPE               2
55 #define LACPDU_ACTOR_INFO_LEN           3
56 #define LACPDU_ACTOR_SYS_PRIORITY       4
57 #define LACPDU_ACTOR_SYSTEM             6
58 #define LACPDU_ACTOR_KEY                12
59 #define LACPDU_ACTOR_PORT_PRIORITY      14
60 #define LACPDU_ACTOR_PORT               16
61 #define LACPDU_ACTOR_STATE              18
62 #define LACPDU_ACTOR_RESERVED           19
63
64 #define LACPDU_PARTNER_TYPE             22
65 #define LACPDU_PARTNER_INFO_LEN         23
66 #define LACPDU_PARTNER_SYS_PRIORITY     24
67 #define LACPDU_PARTNER_SYSTEM           26
68 #define LACPDU_PARTNER_KEY              32
69 #define LACPDU_PARTNER_PORT_PRIORITY    34
70 #define LACPDU_PARTNER_PORT             36
71 #define LACPDU_PARTNER_STATE            38
72 #define LACPDU_PARTNER_RESERVED         39
73
74 #define LACPDU_COLL_TYPE                42
75 #define LACPDU_COLL_INFO_LEN            43
76 #define LACPDU_COLL_MAX_DELAY           44
77 #define LACPDU_COLL_RESERVED            46
78
79 #define LACPDU_TERM_TYPE                58
80 #define LACPDU_TERM_LEN                 59
81 #define LACPDU_TERM_RESERVED            60
82
83 /* Actor and Partner Flag bits */
84 #define LACPDU_FLAGS_ACTIVITY           0x01
85 #define LACPDU_FLAGS_TIMEOUT            0x02
86 #define LACPDU_FLAGS_AGGREGATION        0x04
87 #define LACPDU_FLAGS_SYNC               0x08
88 #define LACPDU_FLAGS_COLLECTING         0x10
89 #define LACPDU_FLAGS_DISTRIB            0x20
90 #define LACPDU_FLAGS_DEFAULTED          0x40
91 #define LACPDU_FLAGS_EXPIRED            0x80
92
93
94 /* MARKER TLVs subtype */
95 #define MARKERPDU_END_MARKER            0x0
96 #define MARKERPDU_MARKER_INFO           0x1
97 #define MARKERPDU_MARKER_RESPONSE       0x2
98
99
100 /* Offsets of fields within a OAMPDU */
101 #define OAMPDU_FLAGS                    1
102 #define OAMPDU_CODE                     3
103
104 #define OAMPDU_HEADER_SIZE              4
105
106 /* OAMPDU Flag bits */
107 #define OAMPDU_FLAGS_LINK_FAULT         0x01
108 #define OAMPDU_FLAGS_DYING_GASP         0x02
109 #define OAMPDU_FLAGS_CRITICAL_EVENT     0x04
110 #define OAMPDU_FLAGS_LOCAL_EVAL         0x08
111 #define OAMPDU_FLAGS_LOCAL_STABLE       0x10
112 #define OAMPDU_FLAGS_REMOTE_EVAL        0x20
113 #define OAMPDU_FLAGS_REMOTE_STABLE      0x40
114
115 /* OAMPDU Code */
116 #define OAMPDU_INFORMATION              0x0
117 #define OAMPDU_EVENT_NOTIFICATION       0x1
118 #define OAMPDU_VAR_REQUEST              0x2
119 #define OAMPDU_VAR_RESPONSE             0x3
120 #define OAMPDU_LOOPBACK_CTRL            0x4
121 #define OAMPDU_VENDOR_SPECIFIC          0xFE
122
123 /* Information Type */
124 #define OAMPDU_INFO_TYPE_ENDMARKER      0x0
125 #define OAMPDU_INFO_TYPE_LOCAL          0x1
126 #define OAMPDU_INFO_TYPE_REMOTE         0x2
127 #define OAMPDU_INFO_TYPE_ORG            0xFE
128
129 /* Size of fields within a OAMPDU Information */
130 #define OAMPDU_INFO_TYPE_SZ             1
131 #define OAMPDU_INFO_LENGTH_SZ           1
132 #define OAMPDU_INFO_VERSION_SZ          1
133 #define OAMPDU_INFO_REVISION_SZ         2
134 #define OAMPDU_INFO_STATE_SZ            1
135 #define OAMPDU_INFO_OAM_CONFIG_SZ       1
136 #define OAMPDU_INFO_OAMPDU_CONFIG_SZ    2
137 #define OAMPDU_INFO_OUI_SZ              3
138 #define OAMPDU_INFO_VENDOR_SPECIFIC_SZ  4
139
140 /* OAM configuration bits */
141
142 #define OAMPDU_INFO_CONFIG_MODE         0x01
143 #define OAMPDU_INFO_CONFIG_UNI          0x02
144 #define OAMPDU_INFO_CONFIG_LPBK         0x04
145 #define OAMPDU_INFO_CONFIG_EVENT        0x08
146 #define OAMPDU_INFO_CONFIG_VAR          0x10
147
148 /* Event Type */
149 #define OAMPDU_EVENT_TYPE_END           0x0
150 #define OAMPDU_EVENT_TYPE_ESPE          0x1
151 #define OAMPDU_EVENT_TYPE_EFE           0x2
152 #define OAMPDU_EVENT_TYPE_EFPE          0x3
153 #define OAMPDU_EVENT_TYPE_EFSSE         0x4
154 #define OAMPDU_EVENT_TYPE_OSE           0xFE
155
156 /* Size of fields within a OAMPDU Event notification */
157 #define OAMPDU_EVENT_SEQUENCE_SZ        2
158 #define OAMPDU_EVENT_TYPE_SZ            1
159 #define OAMPDU_EVENT_LENGTH_SZ          1
160 #define OAMPDU_EVENT_TIMESTAMP_SZ       2
161
162 /* Size of fields within a OAMPDU ESPE: Errored Symbol Period Event TLV */
163 #define OAMPDU_ESPE_WINDOW_SZ           8
164 #define OAMPDU_ESPE_THRESHOLD_SZ        8
165 #define OAMPDU_ESPE_ERRORS_SZ           8
166 #define OAMPDU_ESPE_ERR_TOTAL_SZ        8
167 #define OAMPDU_ESPE_TOTAL_SZ            4
168
169 /* Size of fields within a OAMPDU EFE: Errored Frame Event TLV */
170 #define OAMPDU_EFE_WINDOW_SZ            2
171 #define OAMPDU_EFE_THRESHOLD_SZ         4
172 #define OAMPDU_EFE_ERRORS_SZ            4
173 #define OAMPDU_EFE_ERR_TOTAL_SZ         8
174 #define OAMPDU_EFE_TOTAL_SZ             4
175
176 /* Size of fields within a OAMPDU EFPE: Errored Frame Period Event TLV */
177 #define OAMPDU_EFPE_WINDOW_SZ           4
178 #define OAMPDU_EFPE_THRESHOLD_SZ        4
179 #define OAMPDU_EFPE_ERRORS_SZ           4
180 #define OAMPDU_EFPE_ERR_TOTAL_SZ        8
181 #define OAMPDU_EFPE_TOTAL_SZ            4
182
183 /* Size of fields within a OAMPDU EFSSE: Errored Frame Seconds Summary Event TLV */
184 #define OAMPDU_EFSSE_WINDOW_SZ          2
185 #define OAMPDU_EFSSE_THRESHOLD_SZ       2
186 #define OAMPDU_EFSSE_ERRORS_SZ          2
187 #define OAMPDU_EFSSE_ERR_TOTAL_SZ       4
188 #define OAMPDU_EFSSE_TOTAL_SZ           4
189
190 /* Variable Branch Type */
191 #define OAMPDU_VARS_OBJECT              0x3
192 #define OAMPDU_VARS_PACKAGE             0x4
193 #define OAMPDU_VARS_BINDING             0x6
194 #define OAMPDU_VARS_ATTRIBUTE           0x7
195
196 /* OAMPDU Loopback Control bits */
197 #define OAMPDU_LPBK_ENABLE              0x01
198 #define OAMPDU_LPBK_DISABLE             0x02
199
200
201 static const value_string subtype_vals[] = {
202     { LACP_SUBTYPE, "LACP" },
203     { MARKER_SUBTYPE, "Marker Protocol" },
204     { OAM_SUBTYPE, "OAM" },
205     { 0, NULL }
206 };
207
208 static const value_string marker_vals[] = {
209     { 1, "Marker Information" },
210     { 2, "Marker Response Information" },
211     { 0, NULL }
212 };
213
214 /* see IEEE802.3, table 57-4 */
215 static const value_string code_vals[] = {
216     { 0, "Information" },
217     { 1, "Event Notification" },
218     { 2, "Variable Request" },
219     { 3, "Variable Response" },
220     { 4, "Loopback Control"},
221     { 0xFE, "Organization Specific" },
222     { 0, NULL }
223 };
224
225 /* see IEEE802.3, table 57-6 */
226 static const value_string info_type_vals[] = {
227     { 0, "End of TLV marker" },
228     { 1, "Local Information TLV" },
229     { 2, "Remote Information TLV" },
230     { 0xFE, "Organization Specific Information TLV" },
231     { 0, NULL }
232 };
233
234 /* see IEEE802.3, table 57-12 */
235 static const value_string event_type_vals[] = {
236     { 0, "End of TLV marker" },
237     { 1, "Errored Symbol Period Event" },
238     { 2, "Errored Frame Event" },
239     { 3, "Errored Frame Period Event" },
240     { 4, "Errored Frame Seconds Summary Event" },
241     { 0xFE, "Organization Specific Event TLV" },
242     { 0, NULL }
243 };
244
245
246 /*
247  * In the OAM protocol the {iso(1) member-body(2) us(840) ieee802dot3(10006)
248  * csmacdmgt(30)} prefix for the objects is pre-define. Only the 
249  * managedObjectClass(3) is put in the branch and the leaf is one of the
250  * following value:
251  */
252 static const value_string object_vals[] = {
253     { 1, "macObjectClass" },
254     { 2, "phyObjectClass"},
255     { 3, "repeaterObjectClass"},
256     { 4, "groupObjectClass"},
257     { 5, "repeaterPortObjectClass"},
258     { 6, "mauObjectClass"},
259     { 7, "autoNegObjectClass"},
260     { 8, "macControlObjectClass"},
261     { 9, "macControlFunctionObjectClass"},
262     { 10, "oAggregator"},
263     { 11, "oAggregationPort"},
264     { 12, "oAggPortStats"},
265     { 13, "oAggPortDebugInformation" },
266     { 15, "pseObjectClass"},
267     { 17, "midSpanObjectClass"},
268     { 18, "midSpanGroupObjectClass"},
269     { 19, "ompObjectClass"},
270     { 20, "oamObjectClass" },
271     { 21, "mpcpObjectClass" },
272     { 24, "pafObjectClass" },
273     { 25, "pmeObjectClass"},
274     { 0, NULL }
275 };
276
277 /*
278  * In the OAM protocol the {iso(1) member-body(2) us(840) ieee802dot3(10006)
279  * csmacdmgt(30)} prefix for the objects is pre-define. Only the 
280  * package(4) is put in the branch and the leaf is one of the
281  * following value:
282  */
283 static const value_string package_vals[] = {
284     { 1, "macMandatoryPkg" },
285     { 2, "macRecommendedPkg" },
286     { 3, "macOptionalPkg" },
287     { 4, "macarrayPkg" },
288     { 5, "macExcessiveDeferralPkg" },
289     { 6, "phyRecommendedPkg" },
290     { 7, "phyMultiplePhyPkg" },
291     { 8, "phy100MbpsMonitor" },
292     { 9, "repeaterPerfMonitorPkg"},
293     { 10, "portPerfMonitorPkg"},
294     { 11, "portAddrTrackPkg"},
295     { 12, "port100MbpsMonitor"},
296     { 13, "mauControlPkg"},
297     { 14, "mediaLossTrackingPkg"},
298     { 15, "broadbandMAUPkg"},
299     { 16, "mau100MbpsMonitor"},
300     { 17, "macControlRecommendedPkg" },
301     { 18, "portBurst"},
302     { 19, "pAggregatorMandatory"},
303     { 20, "pAggregatorRecommended"},
304     { 21, "pAggregatorOptional"},
305     { 22, "pAggregationPortMandatory"},
306     { 23, "pAggPortStats"},
307     { 24, "pAggPortDebugInformation"},
308
309     { 27, "pseRecommendedPkg"},
310
311     { 30, "fecMonitor"},
312     { 35, "pcsMonitor"},
313     { 37, "oMPError"},
314     { 38, "pafAggregation"},
315     { 0, NULL }
316 };
317
318 /*
319  * In the OAM protocol the {iso(1) member-body(2) us(840) ieee802dot3(10006)
320  * csmacdmgt(30)} prefix for the objects is pre-define. Only the 
321  * nameBinding(6) is put in the branch and the leaf is one of the
322  * following value:
323  */
324 static const value_string binding_vals[] = {
325     { 26, "repeaterPortName"},
326     { 0, NULL }
327 };
328
329 /*
330  * In the OAM protocol the {iso(1) member-body(2) us(840) ieee802dot3(10006)
331  * csmacdmgt(30)} prefix for the objects is pre-define. Only the 
332  * attribute(7) is put in the branch and the leaf is one of the
333  * following value:
334  */
335 static const value_string attribute_vals[] = {
336     { 1, "aMACID" },
337     { 2, "aFramesTransmittedOK" },
338     { 3, "aSingleCollisionFrames" },
339     { 4, "aMultipleCollisionFrames" },
340     { 5, "aFramesReceivedOK" },
341     { 6, "aFrameCheckSequenceErrors" },
342     { 7, "aAlignmentErrors" },
343     { 8, "aOctetsTransmittedOK" },
344     { 9, "aFramesWithDeferredXmissions" },
345     { 10, "aLateCollisions" },
346     { 11, "aFramesAbortedDueToXSColls" },
347     { 12, "aFramesLostDueToIntMACXmitError" },
348     { 13, "aCarrierSenseErrors" },
349     { 14, "aOctetsReceivedOK" },
350     { 15, "aFramesLostDueToIntMACRcvError" },
351     { 16, "aPromiscuousStatus" },
352     { 17, "aReadMulticastAddressList" },
353     { 18, "aMulticastFramesXmittedOK" },
354     { 19, "aBroadcastFramesXmittedOK" },
355     { 20, "aFramesWithExcessiveDeferral" },
356     { 21, "aMulticastFramesReceivedOK" },
357     { 22, "aBroadcastFramesReceivedOK" },
358     { 23, "aInRangeLengthErrors" },
359     { 24, "aOutOfRangeLengthField" },
360     { 25, "aFrameTooLongErrors" },
361     { 26, "aMACEnableStatus" },
362     { 27, "aTransmitEnableStatus" },
363     { 28, "aMulticastReceiveStatus" },
364     { 29, "aReadWriteMACAddress" },
365     { 30, "aCollisionFrames" },
366     { 31, "aPHYID" },
367     { 32, "aPHYType" },
368     { 33, "aPHYTypeList" },
369     { 34, "aSQETestErrors" },
370     { 35, "aSymbolErrorDuringCarrier" },
371     { 36, "aMIIDetect" },
372     { 37, "aPHYAdminState" },
373     { 38, "aRepeaterID" },
374     { 39, "aRepeaterType" },
375     { 40, "aRepeaterGroupCapacity" },
376     { 41, "aGroupMap" },
377     { 42, "aRepeaterHealthState" },
378     { 43, "aRepeaterHealthText" },
379     { 44, "aRepeaterHealthData" },
380     { 44, "aTransmitCollisions" },
381     { 46, "aGroupID" },
382     { 47, "aGroupPortCapacity" },
383     { 48, "aPortMap" },
384     { 49, "aPortID" },
385     { 50, "aPortAdminState" },
386     { 51, "aAutoPartitionState" },
387     { 52, "aReadableFrames" },
388     { 53, "aReadableOctets" },
389     { 54, "aFrameCheckSequenceErrors" },
390     { 55, "aAlignmentErrors" },
391     { 56, "aFramesTooLong" },
392     { 57, "aShortEvents" },
393     { 58, "aRunts" },
394     { 59, "aCollisions" },
395     { 60, "aLateEvents" },
396     { 61, "aVeryLongEvents" },
397     { 62, "aDataRateMismatches" },
398     { 63, "aAutoPartitions" },
399     { 64, "aIsolates" },
400     { 65, "aSymbolErrorDuringPacket" },
401     { 66, "aLastSourceAddress" },
402     { 67, "aSourceAddressChanges" },
403     { 68, "aMAUID" },
404     { 69, "aMAUType" },
405     { 70, "aMAUTypeList" },
406     { 71, "aMediaAvailable" },
407     { 72, "aLoseMediaCounter" },
408     { 73, "aJabber" },
409     { 74, "aMAUAdminState" },
410     { 75, "aBbMAUXmitRcvSplitType" },
411     { 76, "aBroadbandFrequencies" },
412     { 77, "aFalseCarriers" },
413     { 78, "aAutoNegID" },
414     { 79, "aAutoNegAdminState" },
415     { 80, "aAutoNegRemoteSignaling" },
416     { 81, "aAutoNegAutoConfig" },
417     { 82, "aAutoNegLocalTechnologyAbility" },
418     { 83, "aAutoNegAdvertisedTechnologyAbility" },
419     { 84, "aAutoNegReceivedTechnologyAbility" },
420     { 85, "aAutoNegLocalSelectorAbility" },
421     { 86, "aAutoNegAdvertisedSelectorAbility" },
422     { 87, "aAutoNegReceivedSelectorAbility" },
423
424     { 89, "aMACCapabilities" },
425     { 90, "aDuplexStatus" },
426     { 91, "aIdleErrorCount"},
427     { 92, "aMACControlID" },
428     { 93, "aMACControlFunctionsSupported" },
429     { 94, "aMACControlFramesTransmitted" },
430     { 95, "aMACControlFramesReceived" },
431     { 96, "aUnsupportedOpcodesReceived" },
432     { 97, "aPAUSELinkDelayAllowance" },
433     { 98, "aPAUSEMACCtrlFramesTransmitted" },
434     { 99, "aPAUSEMACCtrlFramesReceived" },
435     { 100, "aBursts" },
436     { 101, "aAggID" },
437     { 102, "aAggDescription" },
438     { 103, "aAggName" },
439     { 104, "aAggActorSystemID" },
440     { 105, "aAggActorSystemPriority" },
441     { 106, "aAggAggregateOrIndividual" },
442     { 107, "aAggActorAdminKey" },
443     { 108, "aAggActorOperKey" },
444     { 109, "aAggMACAddress" },
445     { 110, "aAggPartnerSystemID" },
446     { 111, "aAggPartnerSystemPriority" },
447     { 112, "aAggPartnerOperKey" },
448     { 113, "aAggAdminState" },
449     { 114, "aAggOperState" },
450     { 115, "aAggTimeOfLastOperChange" },
451     { 116, "aAggDataRate" },
452     { 117, "aAggOctetsTxOK" },
453     { 118, "aAggOctetsRxOK" },
454     { 119, "aAggFramesTxOK" },
455     { 120, "aAggFramesRxOK" },
456     { 121, "aAggMulticastFramesTxOK" },
457     { 122, "aAggMulticastFramesRxOK" },
458     { 123, "aAggBroadcastFramesTxOK" },
459     { 124, "aAggBroadcastFramesRxOK" },
460     { 125, "aAggFramesDiscardedOnTx" },
461     { 126, "aAggFramesDiscardedOnRx" },
462     { 127, "aAggFramesWithTxErrors" },
463     { 128, "aAggFramesWithRxErrors" },
464     { 129, "aAggUnknownProtocolFrames" },
465     { 130, "aAggLinkUpDownNotificationEnable" },
466     { 131, "aAggPortList" },
467     { 132, "aAggCollectorMaxDelay" },
468     { 133, "aAggPortID" },
469     { 134, "aAggPortActorSystemPriority" },
470     { 135, "aAggPortActorSystemID" },
471     { 136, "aAggPortActorAdminKey" },
472     { 137, "aAggPortActorOperKey" },
473     { 138, "aAggPortPartnerAdminSystemPriority" },
474     { 139, "aAggPortPartnerOperSystemPriority" },
475     { 140, "aAggPortPartnerAdminSystemID" },
476     { 141, "aAggPortPartnerOperSystemID" },
477     { 142, "aAggPortPartnerAdminKey" },
478     { 143, "aAggPortPartnerOperKey" },
479     { 144, "aAggPortSelectedAggID" },
480     { 145, "aAggPortAttachedAggID" },
481     { 146, "aAggPortActorPort" },
482     { 147, "aAggPortActorPortPriority" },
483     { 148, "aAggPortPartnerAdminPort" },
484     { 149, "aAggPortPartnerOperPort" },
485     { 150, "aAggPortPartnerAdminPortPriority" },
486     { 151, "aAggPortPartnerOperPortPriority" },
487     { 152, "aAggPortActorAdminState" },
488     { 153, "aAggPortActorOperState" },
489     { 154, "aAggPortPartnerAdminState" },
490     { 155, "aAggPortPartnerOperState" },
491     { 156, "aAggPortAggregateOrIndividual" },
492     { 157, "aAggPortStatsID" },
493     { 158, "aAggPortStatsLACPDUsRx" },
494     { 159, "aAggPortStatsMarkerPDUsRx" },
495     { 160, "aAggPortStatsMarkerResponsePDUsRx" },
496     { 161, "aAggPortStatsUnknownRx" },
497     { 162, "aAggPortStatsIllegalRx" },
498     { 163, "aAggPortStatsLACPDUsTx" },
499     { 164, "aAggPortStatsMarkerPDUsTx" },
500     { 165, "aAggPortStatsMarkerResponsePDUsTx" },
501     { 166, "aAggPortDebugInformationID" },
502     { 167, "aAggPortDebugRxState" },
503     { 168, "aAggPortDebugLastRxTime" },
504     { 169, "aAggPortDebugMuxState" },
505     { 170, "aAggPortDebugMuxReason" },
506     { 171, "aAggPortDebugActorChurnState" },
507     { 172, "aAggPortDebugPartnerChurnState" },
508     { 173, "aAggPortDebugActorChurnCount" },
509     { 174, "aAggPortDebugPartnerChurnCount" },
510     { 175, "aAggPortDebugActorSyncTransitionCount" },
511     { 176, "aAggPortDebugPartnerSyncTransitionCount" },
512     { 177, "aAggPortDebugActorChangeCount" },
513     { 178, "aAggPortDebugPartnerChangeCount" },
514
515
516     { 236, "aOAMID" },
517     { 237, "aOAMAdminState" },
518     { 238, "aOAMMode" },
519     { 239, "aOAMRemoteMACAddress" },
520     { 240, "aOAMRemoteConfiguration" },
521     { 241, "aOAMRemotePDUConfiguration" },
522     { 242, "aOAMLocalFlagsField" },
523     { 243, "aOAMRemoteFlagsField" },
524     { 244, "aOAMRemoteRevision" },
525     { 245, "aOAMRemoteState" },
526     { 246, "aOAMRemoteVendorOUI" },
527     { 247, "aOAMRemoteVendorSpecificInfo" },
528
529     { 250, "aOAMUnsupportedCodesRx" },
530     { 251, "aOAMInformationTx" },
531     { 252, "aOAMInformationRx" },
532
533     { 254, "aOAMUniqueEventNotificationRx" },
534     { 255, "aOAMDuplicateEventNotificationRx" },
535     { 256, "aOAMLoopbackControlTx" },
536     { 257, "aOAMLoopbackControlRx" },
537     { 258, "aOAMVariableRequestTx" },
538     { 259, "aOAMVariableRequestRx" },
539     { 260, "aOAMVariableResponseTx" },
540     { 261, "aOAMVariableResponseRx" },
541     { 262, "aOAMOrganizationSpecificTx" },
542     { 263, "aOAMOrganizationSpecificRx" },
543     { 264, "aOAMLocalErrSymPeriodConfig" },
544     { 265, "aOAMLocalErrSymPeriodEvent" },
545     { 266, "aOAMLocalErrFrameConfig" },
546     { 267, "aOAMLocalErrFrameEvent" },
547     { 268, "aOAMLocalErrFramePeriodConfig" },
548     { 269, "aOAMLocalErrFramePeriodEvent" },
549     { 270, "aOAMLocalErrFrameSecsSummaryConfig" },
550     { 271, "aOAMLocalErrFrameSecsSummaryEvent" },
551     { 272, "aOAMRemoteErrSymPeriodEvent" },
552     { 273, "aOAMRemoteErrFrameEvent" },
553     { 274, "aOAMRemoteErrFramePeriodEvent" },
554     { 275, "aOAMRemoteErrFrameSecsSummaryEvent" },
555     { 276, "aFramesLostDueToOAMError" },
556
557     { 333, "aOAMDiscoveryState"},
558     { 334, "aOAMLocalConfiguration"},
559     { 335, "aOAMLocalPDUConfiguration"},
560     { 336, "aOAMLocalRevision"},
561     { 337, "aOAMLocalState"},
562     { 338, "aOAMUnsupportedCodesTx" },
563     { 339, "aOAMUniqueEventNotificationTx" },
564     { 340, "aOAMDuplicateEventNotificationTx" },
565     { 0, NULL }
566 };
567
568 /*
569  * In the OAM protocol the {iso(1) member-body(2) us(840) ieee802dot3(10006)
570  * csmacdmgt(30)} prefix for the objects is pre-define. Only the 
571  * package(4) is put in the branch and the leaf is one of the
572  * following value:
573  */
574 static const value_string indication_vals[] = {
575     { 0x01, "Variable Container(s) exceeded OAMPDU data field" },
576
577     { 0x20, "Attribute->Unable to return due to an undetermined error" },
578     { 0x21, "Attribute->Unable to return because it is not supported" },
579     { 0x22, "Attribute->May have been corrupted due to reset" },
580     { 0x23, "Attribute->Unable to return due to a hardware failure" },
581     { 0x24, "Attribute->Experience an overflow error" },
582
583     { 0x40, "Object->End of object indication" },
584     { 0x41, "Object->Unable to return due to an undetermined error" },
585     { 0x42, "Object->Unable to return because it is not supported" },
586     { 0x43, "Object->May have been corrupted due to reset" },
587     { 0x44, "Object->Unable to return due to a hardware failure" },
588
589     { 0x60, "Package->End of package indication" },
590     { 0x61, "Package->Unable to return due to an undetermined error" },
591     { 0x62, "Package->Unable to return because it is not supported" },
592     { 0x63, "Package->May have been corrupted due to reset" },
593     { 0x64, "Package->Unable to return due to a hardware failure" },
594     { 0, NULL }
595 };
596
597 static const value_string status_vals[] _U_ = {
598     { 0x00, "Unsatisfied, can't complete" },
599     { 0x01, "Discovery in process" },
600     { 0x02, "Satisfied, Discovery complete" },
601     { 0x10, "Satisfied, Discovery complete" },
602     { 0x20, "Discovery in process" },
603     { 0x40, "Satisfied, Discovery complete" },
604     { 0x50, "BUG Satisfied, Discovery complete" },
605     { 0x80, "Discovery in process" },
606
607     { 0, NULL }
608 };
609
610 static const value_string branch_vals[] = {
611     { 3, "Object" },
612     { 4, "Package" },
613     { 6, "nameBinding" },
614     { 7, "Attribute" },
615     { 0, NULL }
616 };
617
618 static const value_string parser_vals[] = {
619     { 0, "Forward non-OAMPDUs to higher sublayer" },
620     { 1, "Loopback non-OAMPDUs to the lower sublayer" },
621     { 2, "Discarding non-OAMPDUs" },
622     { 3, "Reserved" },
623     { 0, NULL }
624 };
625
626 static const true_false_string mux = {
627     "Discard non-OAMPDUs",
628     "Forward non-OAMPDUs to lower sublayer"
629 };
630
631 static const true_false_string oam_mode = {
632     "DTE configured in Active mode",
633     "DTE configured in Passive mode"
634 };
635
636 static const true_false_string oam_uni = {
637     "DTE is capable of sending OAMPDUs when rcv path is down",
638     "DTE is not capable of sending OAMPDUs when rcv path is down"
639 };
640
641 static const true_false_string oam_lpbk = {
642     "DTE is capable of OAM remote loopback mode",
643     "DTE is not capable of OAM remote loopback mode"
644 };
645
646 static const true_false_string oam_event = {
647     "DTE supports interpreting Link Events",
648     "DTE does not support interpreting Link Events"
649 };
650
651 static const true_false_string oam_var = {
652     "DTE supports sending Variable Response",
653     "DTE does not support sending Variable Response"
654 };
655
656
657 /* Initialise the protocol and registered fields */
658 static int proto_slow = -1;
659
660 static int hf_slow_subtype = -1;
661
662 static int hf_lacpdu_version_number = -1;
663 static int hf_lacpdu_actor_type = -1;
664 static int hf_lacpdu_actor_info_len = -1;
665 static int hf_lacpdu_actor_sys_priority = -1;
666 static int hf_lacpdu_actor_sys = -1;
667 static int hf_lacpdu_actor_key = -1;
668 static int hf_lacpdu_actor_port_priority = -1;
669 static int hf_lacpdu_actor_port = -1;
670 static int hf_lacpdu_actor_state = -1;
671 static int hf_lacpdu_flags_a_activity = -1;
672 static int hf_lacpdu_flags_a_timeout = -1;
673 static int hf_lacpdu_flags_a_aggregation = -1;
674 static int hf_lacpdu_flags_a_sync = -1;
675 static int hf_lacpdu_flags_a_collecting = -1;
676 static int hf_lacpdu_flags_a_distrib = -1;
677 static int hf_lacpdu_flags_a_defaulted = -1;
678 static int hf_lacpdu_flags_a_expired = -1;
679 static int hf_lacpdu_actor_reserved = -1;
680
681 static int hf_lacpdu_partner_type = -1;
682 static int hf_lacpdu_partner_info_len = -1;
683 static int hf_lacpdu_partner_sys_priority = -1;
684 static int hf_lacpdu_partner_sys = -1;
685 static int hf_lacpdu_partner_key = -1;
686 static int hf_lacpdu_partner_port_priority = -1;
687 static int hf_lacpdu_partner_port = -1;
688 static int hf_lacpdu_partner_state = -1;
689 static int hf_lacpdu_flags_p_activity = -1;
690 static int hf_lacpdu_flags_p_timeout = -1;
691 static int hf_lacpdu_flags_p_aggregation = -1;
692 static int hf_lacpdu_flags_p_sync = -1;
693 static int hf_lacpdu_flags_p_collecting = -1;
694 static int hf_lacpdu_flags_p_distrib = -1;
695 static int hf_lacpdu_flags_p_defaulted = -1;
696 static int hf_lacpdu_flags_p_expired = -1;
697 static int hf_lacpdu_partner_reserved = -1;
698
699 static int hf_lacpdu_coll_type = -1;
700 static int hf_lacpdu_coll_info_len = -1;
701 static int hf_lacpdu_coll_max_delay = -1;
702 static int hf_lacpdu_coll_reserved = -1;
703
704 static int hf_lacpdu_term_type = -1;
705 static int hf_lacpdu_term_len = -1;
706 static int hf_lacpdu_term_reserved = -1;
707
708 /* MARKER */
709 static int hf_marker_version_number = -1;
710 static int hf_marker_tlv_type = -1;
711 static int hf_marker_tlv_length = -1;
712 static int hf_marker_req_port = -1;
713 static int hf_marker_req_system = -1;
714 static int hf_marker_req_trans_id = -1;
715
716 /* OAM */
717 static int hf_oampdu_flags = -1;
718 static int hf_oampdu_flags_link_fault = -1;
719 static int hf_oampdu_flags_dying_gasp = -1;
720 static int hf_oampdu_flags_critical_event = -1;
721 static int hf_oampdu_flags_local_evaluating = -1;
722 static int hf_oampdu_flags_local_stable = -1;
723 static int hf_oampdu_flags_remote_evaluating = -1;
724 static int hf_oampdu_flags_remote_stable = -1;
725 static int hf_oampdu_code = -1;
726
727 static int hf_oampdu_info_type = -1;
728 static int hf_oampdu_info_len = -1;
729 static int hf_oampdu_info_version = -1;
730 static int hf_oampdu_info_revision = -1;
731 static int hf_oampdu_info_state = -1;
732 static int hf_oampdu_info_oamConfig = -1;
733 static int hf_oampdu_info_oampduConfig = -1;
734 static int hf_oampdu_info_oui = -1;
735 static int hf_oampdu_info_vendor = -1;
736
737 static int hf_oampdu_info_state_parser = -1;
738 static int hf_oampdu_info_state_mux = -1;
739
740 static int hf_oampdu_info_oamConfig_mode = -1;
741 static int hf_oampdu_info_oamConfig_uni = -1;
742 static int hf_oampdu_info_oamConfig_lpbk = -1;
743 static int hf_oampdu_info_oamConfig_event = -1;
744 static int hf_oampdu_info_oamConfig_var = -1;
745
746 static int hf_oampdu_event_type = -1;
747 static int hf_oampdu_event_sequence = -1;
748 static int hf_oampdu_event_length = -1;
749 static int hf_oampdu_event_timeStamp = -1;
750
751 static int hf_oampdu_event_espeWindow = -1;
752 static int hf_oampdu_event_espeThreshold = -1;
753 static int hf_oampdu_event_espeErrors = -1;
754 static int hf_oampdu_event_espeTotalErrors = -1;
755 static int hf_oampdu_event_espeTotalEvents = -1;
756
757 static int hf_oampdu_event_efeWindow = -1;
758 static int hf_oampdu_event_efeThreshold = -1;
759 static int hf_oampdu_event_efeErrors = -1;
760 static int hf_oampdu_event_efeTotalErrors = -1;
761 static int hf_oampdu_event_efeTotalEvents = -1;
762
763 static int hf_oampdu_event_efpeWindow = -1;
764 static int hf_oampdu_event_efpeThreshold = -1;
765 static int hf_oampdu_event_efpeErrors = -1;
766 static int hf_oampdu_event_efpeTotalErrors = -1;
767 static int hf_oampdu_event_efpeTotalEvents = -1;
768
769 static int hf_oampdu_event_efsseWindow = -1;
770 static int hf_oampdu_event_efsseThreshold = -1;
771 static int hf_oampdu_event_efsseErrors = -1;
772 static int hf_oampdu_event_efsseTotalErrors = -1;
773 static int hf_oampdu_event_efsseTotalEvents = -1;
774
775 static int hf_oampdu_variable_branch = -1;
776 static int hf_oampdu_variable_object = -1;
777 static int hf_oampdu_variable_package = -1;
778 static int hf_oampdu_variable_binding = -1;
779 static int hf_oampdu_variable_attribute = -1;
780 static int hf_oampdu_variable_width = -1;
781 static int hf_oampdu_variable_indication = -1;
782 static int hf_oampdu_variable_value = -1;
783
784 static int hf_oampdu_lpbk = -1;
785 static int hf_oampdu_lpbk_enable = -1;
786 static int hf_oampdu_lpbk_disable = -1;
787
788
789 /* Initialise the subtree pointers */
790
791 static gint ett_pdu = -1;
792
793 static gint ett_lacpdu = -1;
794 static gint ett_lacpdu_a_flags = -1;
795 static gint ett_lacpdu_p_flags = -1;
796
797 static gint ett_marker = -1;
798
799 static gint ett_oampdu = -1;
800 static gint ett_oampdu_flags = -1;
801
802 static gint ett_oampdu_local_info = -1;
803 static gint ett_oampdu_local_info_state = -1;
804 static gint ett_oampdu_local_info_config = -1;
805 static gint ett_oampdu_remote_info = -1;
806 static gint ett_oampdu_remote_info_state = -1;
807 static gint ett_oampdu_remote_info_config = -1;
808 static gint ett_oampdu_org_info = -1;
809
810 static gint ett_oampdu_event_espe = -1;
811 static gint ett_oampdu_event_efe = -1;
812 static gint ett_oampdu_event_efpe = -1;
813 static gint ett_oampdu_event_efsse = -1;
814 static gint ett_oampdu_event_ose = -1;
815
816 static gint ett_oampdu_lpbk_ctrl = -1;
817
818 static const char initial_sep[] = " (";
819 static const char cont_sep[] = ", ";
820
821
822 #define APPEND_BOOLEAN_FLAG(flag, item, string) \
823     if(flag){                            \
824         if(item)                        \
825             proto_item_append_text(item, string, sep);    \
826         sep = cont_sep;                        \
827     }
828
829
830 #define APPEND_OUI_NAME(item, string, mac) \
831         if(item){                        \
832             string = get_manuf_name(mac); \
833             proto_item_append_text(item, " (");    \
834             proto_item_append_text(item, "%s", string);    \
835             proto_item_append_text(item, ")");    \
836         }
837
838 static void
839 dissect_lacp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
840
841 static void
842 dissect_marker_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
843
844 static void
845 dissect_oampdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
846
847 static void
848 dissect_oampdu_information(tvbuff_t *tvb, proto_tree *tree);
849
850 static void
851 dissect_oampdu_event_notification(tvbuff_t *tvb, proto_tree *tree);
852
853 static void
854 dissect_oampdu_variable_request(tvbuff_t *tvb, proto_tree *tree);
855
856 static void
857 dissect_oampdu_variable_response(tvbuff_t *tvb, proto_tree *tree);
858
859 static void
860 dissect_oampdu_loopback_control(tvbuff_t *tvb, proto_tree *tree);
861
862 static void
863 dissect_oampdu_vendor_specific(tvbuff_t *tvb, proto_tree *tree);
864
865
866 /*
867  * Name: dissect_slow_protocols
868  *
869  * Description:
870  *    This function is used to dissect the slow protocols define in IEEE802.3
871  *    CSMA/CD. The current slow protocols subtype are define in ANNEX 43B of
872  *    the 802.3 document. In case of an unsupported slow protocols, we only
873  *    fill the protocol and info columns.
874  *
875  * Input Arguments:
876  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
877  *    pinfo: structure associate with the rcv packet (see packet_info.h).
878  *    tree: the protocol tree associate with the rcv packet (see proto.h).
879  *
880  * Return Values:
881  *    None
882  *
883  * Notes:
884  *    Dominique Bastien (dbastien@accedian.com)
885  *      + add support for OAM slow protocol (defined in clause 57).
886  *      + add support for Marker slow protocol (defined in clause 43).
887  */
888 static void
889 dissect_slow_protocols(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
890 {
891     guint8 subtype;
892     proto_tree *pdu_tree;
893     proto_item *pdu_item;
894
895     subtype = tvb_get_guint8(tvb, 0);
896
897     switch (subtype)
898     {
899         case LACP_SUBTYPE:
900             dissect_lacp_pdu(tvb, pinfo, tree);
901             break;
902         case MARKER_SUBTYPE:
903             dissect_marker_pdu(tvb, pinfo, tree);
904             break;
905         case OAM_SUBTYPE:
906             dissect_oampdu(tvb, pinfo, tree);
907             break;
908         default:
909         {
910             if (check_col(pinfo->cinfo, COL_PROTOCOL))
911                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Slow Protocols");
912
913             if (check_col(pinfo->cinfo, COL_INFO))
914                 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown Subtype = %u.", subtype);
915
916             if (tree)
917             {
918                 pdu_item = proto_tree_add_item(tree, proto_slow, tvb,
919                         0, -1, FALSE);
920                 pdu_tree = proto_item_add_subtree(pdu_item, ett_pdu);
921
922                 /* Subtype */
923                 proto_tree_add_item(pdu_tree, hf_slow_subtype, tvb,
924                         0, 1, FALSE);
925             }
926
927             break;
928         }
929     }
930 }
931
932 /*
933  * Name: dissect_lacp_pdu
934  *
935  * Description:
936  *    This function is used to dissect the Link Aggregation Control Protocol
937  *    slow protocols define in IEEE802.3 clause 43.3.
938  *
939  * Input Arguments:
940  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
941  *    pinfo: structure associate with the rcv packet (see packet_info.h).
942  *    tree: the protocol tree associate with the rcv packet (see proto.h).
943  *
944  * Return Values: None
945  *
946  * Notes:
947  */
948 static void
949 dissect_lacp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
950 {
951     guint16 raw_word;
952     guint8  raw_octet;
953
954     guint8  flags;
955
956     const guint8 *a_sys;
957     const guint8 *p_sys;
958     const guint8 *resv_bytes;
959
960     proto_tree *lacpdu_tree;
961     proto_item *lacpdu_item;
962     proto_tree *actor_flags_tree;
963     proto_item *actor_flags_item;
964     proto_tree *partner_flags_tree;
965     proto_item *partner_flags_item;
966
967     const char *sep;
968
969
970     if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
971         col_set_str(pinfo->cinfo, COL_PROTOCOL, "LACP");
972
973     if (check_col(pinfo->cinfo, COL_INFO)) 
974         col_set_str(pinfo->cinfo, COL_INFO, "Link Aggregation Control Protocol");
975
976     if (tree)
977     {
978         /* Add LACP Heading */
979         lacpdu_item = proto_tree_add_protocol_format(tree, proto_slow, tvb,
980                 0, -1, "Link Aggregation Control Protocol");
981         lacpdu_tree = proto_item_add_subtree(lacpdu_item, ett_lacpdu);
982
983         /* Subtype */
984         proto_tree_add_item(lacpdu_tree, hf_slow_subtype, tvb,
985                 0, 1, FALSE);
986
987         /* Version Number */
988         raw_octet = tvb_get_guint8(tvb, LACPDU_VERSION_NUMBER);
989         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_version_number, tvb,
990                 LACPDU_VERSION_NUMBER, 1, raw_octet);
991
992         if (check_col(pinfo->cinfo, COL_INFO))
993         {
994             col_append_fstr(pinfo->cinfo, COL_INFO, "Version %d.  ", raw_octet);
995         }
996
997         /* Actor Type */
998         raw_octet = tvb_get_guint8(tvb, LACPDU_ACTOR_TYPE);
999         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_type, tvb,
1000                 LACPDU_ACTOR_TYPE, 1, raw_octet);
1001
1002         /* Actor Info Length */
1003         raw_octet = tvb_get_guint8(tvb, LACPDU_ACTOR_INFO_LEN);
1004         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_info_len, tvb,
1005                 LACPDU_ACTOR_INFO_LEN, 1, raw_octet);
1006
1007         /* Actor System Priority */
1008
1009         raw_word = tvb_get_ntohs(tvb, LACPDU_ACTOR_SYS_PRIORITY);
1010         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_sys_priority, tvb,
1011                 LACPDU_ACTOR_SYS_PRIORITY, 2, raw_word);
1012         /* Actor System */
1013
1014         a_sys = tvb_get_ptr(tvb, LACPDU_ACTOR_SYSTEM , 6);
1015         proto_tree_add_ether(lacpdu_tree, hf_lacpdu_actor_sys, tvb,
1016                 LACPDU_ACTOR_SYSTEM, 6, a_sys);
1017
1018         /* Actor Key */
1019
1020         raw_word = tvb_get_ntohs(tvb, LACPDU_ACTOR_KEY);
1021         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_key, tvb,
1022                 LACPDU_ACTOR_KEY, 2, raw_word);
1023
1024         /* Actor Port Priority */
1025
1026         raw_word = tvb_get_ntohs(tvb, LACPDU_ACTOR_PORT_PRIORITY);
1027         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_port_priority, tvb,
1028                 LACPDU_ACTOR_PORT_PRIORITY, 2, raw_word);
1029
1030         /* Actor Port */
1031
1032         raw_word = tvb_get_ntohs(tvb, LACPDU_ACTOR_PORT);
1033         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_port, tvb,
1034                 LACPDU_ACTOR_PORT, 2, raw_word);
1035
1036         if (check_col(pinfo->cinfo, COL_INFO))
1037         {
1038         col_append_fstr(pinfo->cinfo, COL_INFO, "Actor Port = %d ", raw_word);
1039         }
1040
1041         /* Actor State */
1042
1043         flags = tvb_get_guint8(tvb, LACPDU_ACTOR_STATE);
1044         actor_flags_item = proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_state, tvb,
1045                 LACPDU_ACTOR_STATE, 1, flags);
1046         actor_flags_tree = proto_item_add_subtree(actor_flags_item, ett_lacpdu_a_flags);
1047
1048         sep = initial_sep;
1049
1050         /* Activity Flag */
1051
1052         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_ACTIVITY, actor_flags_item,
1053                 "%sActivity");
1054         proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_activity, tvb,
1055                 LACPDU_ACTOR_STATE, 1, flags);
1056
1057         /* Timeout Flag */
1058
1059         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_TIMEOUT, actor_flags_item,
1060                 "%sTimeout");
1061         proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_timeout, tvb,
1062                 LACPDU_ACTOR_STATE, 1, flags);
1063
1064         /* Aggregation Flag */
1065
1066         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_AGGREGATION, actor_flags_item,
1067                 "%sAggregation");
1068         proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_aggregation, tvb,
1069                 LACPDU_ACTOR_STATE, 1, flags);
1070
1071         /* Synchronization Flag */
1072
1073         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_SYNC, actor_flags_item,
1074                 "%sSynchronization");
1075         proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_sync, tvb,
1076                 LACPDU_ACTOR_STATE, 1, flags);
1077
1078         /* Collecting Flag */
1079
1080         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_COLLECTING, actor_flags_item,
1081                 "%sCollecting");
1082         proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_collecting, tvb,
1083                 LACPDU_ACTOR_STATE, 1, flags);
1084
1085
1086         /* Distributing Flag */
1087
1088         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DISTRIB, actor_flags_item,
1089                 "%sDistributing");
1090         proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_distrib, tvb,
1091                 LACPDU_ACTOR_STATE, 1, flags);
1092
1093         /* Defaulted Flag */
1094
1095         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DEFAULTED, actor_flags_item,
1096                 "%sDefaulted");
1097         proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_defaulted, tvb,
1098                 LACPDU_ACTOR_STATE, 1, flags);
1099
1100         /* Expired Flag */
1101
1102         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_EXPIRED, actor_flags_item,
1103                 "%sExpired");
1104         proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_expired, tvb,
1105                 LACPDU_ACTOR_STATE, 1, flags);
1106
1107         if (sep != initial_sep)
1108         {
1109             /* We put something in; put in the terminating ")" */
1110             proto_item_append_text(actor_flags_item, ")");
1111         }
1112
1113         /* Actor Reserved */
1114
1115         resv_bytes = tvb_get_ptr(tvb, LACPDU_ACTOR_RESERVED, 3);
1116         proto_tree_add_bytes(lacpdu_tree, hf_lacpdu_actor_reserved, tvb,
1117                 LACPDU_ACTOR_RESERVED, 3, resv_bytes);
1118
1119
1120         /* Partner Type */
1121         raw_octet = tvb_get_guint8(tvb, LACPDU_PARTNER_TYPE);
1122         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_type, tvb,
1123                 LACPDU_PARTNER_TYPE, 1, raw_octet);
1124
1125         /* Partner Info Length */
1126         raw_octet = tvb_get_guint8(tvb, LACPDU_PARTNER_INFO_LEN);
1127         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_info_len, tvb,
1128                 LACPDU_PARTNER_INFO_LEN, 1, raw_octet);
1129
1130         /* Partner System Priority */
1131
1132         raw_word = tvb_get_ntohs(tvb, LACPDU_PARTNER_SYS_PRIORITY);
1133         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_sys_priority, tvb,
1134                 LACPDU_PARTNER_SYS_PRIORITY, 2, raw_word);
1135
1136         /* Partner System */
1137
1138         p_sys = tvb_get_ptr(tvb, LACPDU_PARTNER_SYSTEM, 6);
1139         proto_tree_add_ether(lacpdu_tree, hf_lacpdu_partner_sys, tvb,
1140                 LACPDU_PARTNER_SYSTEM, 6, p_sys);
1141
1142         /* Partner Key */
1143
1144         raw_word = tvb_get_ntohs(tvb, LACPDU_PARTNER_KEY);
1145         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_key, tvb,
1146                 LACPDU_PARTNER_KEY, 2, raw_word);
1147
1148         /* Partner Port Priority */
1149
1150         raw_word = tvb_get_ntohs(tvb, LACPDU_PARTNER_PORT_PRIORITY);
1151         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_port_priority, tvb,
1152                 LACPDU_PARTNER_PORT_PRIORITY, 2, raw_word);
1153
1154         /* Partner Port */
1155
1156         raw_word = tvb_get_ntohs(tvb, LACPDU_PARTNER_PORT);
1157         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_port, tvb,
1158                 LACPDU_PARTNER_PORT, 2, raw_word);
1159
1160         if (check_col(pinfo->cinfo, COL_INFO))
1161         {
1162             col_append_fstr(pinfo->cinfo, COL_INFO, "Partner Port = %d ", raw_word);
1163         }
1164
1165         /* Partner State */
1166
1167         flags = tvb_get_guint8(tvb, LACPDU_PARTNER_STATE);
1168         partner_flags_item = proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_state, tvb,
1169                 LACPDU_PARTNER_STATE, 1, flags);
1170         partner_flags_tree = proto_item_add_subtree(partner_flags_item, ett_lacpdu_p_flags);
1171
1172         sep = initial_sep;
1173
1174         /* Activity Flag */
1175
1176         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_ACTIVITY, partner_flags_item,
1177                 "%sActivity");
1178         proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_activity, tvb,
1179                 LACPDU_PARTNER_STATE, 1, flags);
1180
1181         /* Timeout Flag */
1182
1183         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_TIMEOUT, partner_flags_item,
1184                 "%sTimeout");
1185         proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_timeout, tvb,
1186                 LACPDU_PARTNER_STATE, 1, flags);
1187
1188         /* Aggregation Flag */
1189
1190         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_AGGREGATION, partner_flags_item,
1191                 "%sAggregation");
1192         proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_aggregation, tvb,
1193                 LACPDU_PARTNER_STATE, 1, flags);
1194
1195         /* Synchronization Flag */
1196
1197         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_SYNC, partner_flags_item,
1198                 "%sSynchronization");
1199         proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_sync, tvb,
1200                 LACPDU_PARTNER_STATE, 1, flags);
1201
1202         /* Collecting Flag */
1203
1204         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_COLLECTING, partner_flags_item,
1205                 "%sCollecting");
1206         proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_collecting, tvb,
1207                 LACPDU_PARTNER_STATE, 1, flags);
1208
1209
1210         /* Distributing Flag */
1211
1212         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DISTRIB, partner_flags_item,
1213                 "%sDistributing");
1214         proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_distrib, tvb,
1215                 LACPDU_PARTNER_STATE, 1, flags);
1216
1217         /* Defaulted Flag */
1218
1219         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DEFAULTED, partner_flags_item,
1220                 "%sDefaulted");
1221         proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_defaulted, tvb,
1222                 LACPDU_PARTNER_STATE, 1, flags);
1223
1224         /* Expired Flag */
1225
1226         APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_EXPIRED, partner_flags_item,
1227                 "%sExpired");
1228         proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_expired, tvb,
1229                 LACPDU_PARTNER_STATE, 1, flags);
1230
1231         if (sep != initial_sep)
1232         {
1233             /* We put something in; put in the terminating ")" */
1234             proto_item_append_text(partner_flags_item, ")");
1235         }
1236
1237         /* Partner Reserved */
1238
1239         resv_bytes = tvb_get_ptr(tvb, LACPDU_PARTNER_RESERVED, 3);
1240         proto_tree_add_bytes(lacpdu_tree, hf_lacpdu_partner_reserved, tvb,
1241                 LACPDU_PARTNER_RESERVED, 3, resv_bytes);
1242
1243
1244         /* Collector Type */
1245         raw_octet = tvb_get_guint8(tvb, LACPDU_COLL_TYPE);
1246         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_coll_type, tvb,
1247                 LACPDU_COLL_TYPE, 1, raw_octet);
1248
1249         /* Collector Info Length */
1250         raw_octet = tvb_get_guint8(tvb, LACPDU_COLL_INFO_LEN);
1251         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_coll_info_len, tvb,
1252                 LACPDU_COLL_INFO_LEN, 1, raw_octet);
1253
1254         /* Collector Max Delay */
1255
1256         raw_word = tvb_get_ntohs(tvb, LACPDU_COLL_MAX_DELAY);
1257         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_coll_max_delay, tvb,
1258                 LACPDU_COLL_MAX_DELAY, 2, raw_word);
1259
1260         /* Collector Reserved */
1261
1262         resv_bytes = tvb_get_ptr(tvb, LACPDU_COLL_RESERVED, 12);
1263         proto_tree_add_bytes(lacpdu_tree, hf_lacpdu_coll_reserved, tvb,
1264                 LACPDU_COLL_RESERVED, 12, resv_bytes);
1265
1266         /* Terminator Type */
1267         raw_octet = tvb_get_guint8(tvb, LACPDU_TERM_TYPE);
1268         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_term_type, tvb,
1269                 LACPDU_TERM_TYPE, 1, raw_octet);
1270
1271         /* Terminator Info Length */
1272         raw_octet = tvb_get_guint8(tvb, LACPDU_TERM_LEN);
1273         proto_tree_add_uint(lacpdu_tree, hf_lacpdu_term_len, tvb,
1274                 LACPDU_TERM_LEN, 1, raw_octet);
1275
1276         /* Terminator Reserved */
1277
1278         resv_bytes = tvb_get_ptr(tvb, LACPDU_TERM_RESERVED, 50);
1279         proto_tree_add_bytes(lacpdu_tree, hf_lacpdu_term_reserved, tvb,
1280                 LACPDU_TERM_RESERVED, 50, resv_bytes);
1281     }
1282 }
1283
1284 /*
1285  * Name: dissect_marker_pdu
1286  *
1287  * Description:
1288  *    This function is used to dissect the Link Aggregation Marker Protocol
1289  *    slow protocols define in IEEE802.3 clause 43.5 (The PDUs are define
1290  *    in section 43.5.3.2). The TLV type are, 0x01 for a marker TLV and 0x02 
1291  *    for a marker response. A value of 0x00 indicate an end of message.
1292  *
1293  * Input Arguments:
1294  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
1295  *    pinfo: structure associate with the rcv packet (see packet_info.h).
1296  *    tree: the protocol tree associate with the rcv packet (see proto.h).
1297  *
1298  * Return Values: None
1299  *
1300  * Notes:
1301  *    Dominique Bastien (dbastien@accedian.com)
1302  *      + add support for MARKER and MARKER Response PDUs.
1303  */
1304 static void
1305 dissect_marker_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1306 {
1307     guint8  raw_octet;
1308     guint16 raw_word;
1309     guint32 dword;
1310     guint32 offset;
1311
1312     const guint8 *a_sys;
1313
1314     proto_tree *marker_tree;
1315     proto_item *marker_item;
1316
1317
1318     if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
1319         col_set_str(pinfo->cinfo, COL_PROTOCOL, "MARKER");
1320
1321     if (check_col(pinfo->cinfo, COL_INFO)) 
1322         col_set_str(pinfo->cinfo, COL_INFO, "Marker Protocol");
1323
1324     if (tree)
1325     {
1326         marker_item = proto_tree_add_protocol_format(tree, proto_slow, tvb,
1327                             0, -1, "Marker Protocol");
1328         marker_tree = proto_item_add_subtree(marker_item, ett_marker);
1329
1330         /* Subtype */
1331         proto_tree_add_item(marker_tree, hf_slow_subtype, tvb,
1332                 0, 1, FALSE);
1333
1334         offset = 1;
1335
1336         /* Version Number */
1337         raw_octet = tvb_get_guint8(tvb, offset);
1338         proto_tree_add_uint(marker_tree, hf_marker_version_number, tvb,
1339                 offset, 1, raw_octet);
1340
1341         offset += 1;
1342
1343         while (1)
1344         {
1345             /* TLV Type */
1346             raw_octet = tvb_get_guint8(tvb, offset);
1347
1348             if (raw_octet==0) break;
1349
1350             proto_tree_add_uint(marker_tree, hf_marker_tlv_type, tvb,
1351                     offset, 1, raw_octet);
1352
1353             offset += 1;
1354
1355             /* TLV Length */
1356             raw_octet = tvb_get_guint8(tvb, offset);
1357             proto_tree_add_uint(marker_tree, hf_marker_tlv_length, tvb,
1358                     offset, 1, raw_octet);
1359             offset += 1;
1360
1361             /* Requester Port */
1362             raw_word = tvb_get_ntohs(tvb, offset);
1363             proto_tree_add_uint(marker_tree, hf_marker_req_port, tvb,
1364                     offset, 2, raw_word);
1365             offset += 2;
1366
1367             /* Requester System */
1368             a_sys = tvb_get_ptr(tvb, offset , 6);
1369             proto_tree_add_ether(marker_tree, hf_marker_req_system, tvb,
1370                     offset, 6, a_sys);
1371             offset += 6;
1372
1373             /* Requester Transaction ID */
1374             dword = tvb_get_ntohl(tvb, offset);
1375             proto_tree_add_uint(marker_tree, hf_marker_req_trans_id, tvb,
1376                     offset, 4, dword);
1377             offset += 2;
1378
1379             /* Pad to align */
1380             offset += 2;
1381         }
1382     }
1383 }
1384
1385 /*
1386  * Name: dissect_oampdu
1387  *
1388  * Description:
1389  *    This function is used to dissect the Operation, Administration, and 
1390  *    Maintenance slow protocol define in IEEE802.3 clause 57 (The OAMPDUs
1391  *    common part is define in section 57.4).
1392  *
1393  *    Only the 6 folowing code are currently define in the 2004 version of this
1394  *    protocol:
1395  *       OAMPDU_INFORMATION: 0x0
1396  *       OAMPDU_EVENT_NOTIFICATION: 0x1
1397  *       OAMPDU_VAR_REQUEST: 0x2
1398  *       OAMPDU_VAR_RESPONSE: 0x3
1399  *       OAMPDU_LOOPBACK_CTRL: 0x4
1400  *       OAMPDU_VENDOR_SPECIFIC: 0xFE
1401  *
1402  * Input Arguments:
1403  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
1404  *    pinfo: structure associate with the rcv packet (see packet_info.h).
1405  *    tree: the protocol tree associate with the rcv packet (see proto.h).
1406  *
1407  * Return Values: None
1408  *
1409  * Notes:
1410  *    Dominique Bastien (dbastien@accedian.com)
1411  *      + add support for 802.3ah-2004.
1412  */
1413 static void
1414 dissect_oampdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1415 {
1416     guint8    oampdu_code;
1417     guint16   flags,state;
1418     guint32   i;
1419
1420     proto_tree *oampdu_tree;
1421     proto_item *oampdu_item;
1422     proto_tree *flags_tree;
1423     proto_item *flags_item;
1424
1425     const char *sep = initial_sep;
1426
1427     if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
1428         col_set_str(pinfo->cinfo, COL_PROTOCOL, "OAM");
1429
1430     oampdu_code = tvb_get_guint8(tvb, OAMPDU_CODE);
1431
1432     switch (oampdu_code)
1433     {
1434         case OAMPDU_INFORMATION:
1435             if (check_col(pinfo->cinfo, COL_INFO)) 
1436                 col_set_str(pinfo->cinfo, COL_INFO, "OAMPDU: Information");
1437             break;
1438         case OAMPDU_EVENT_NOTIFICATION:
1439             if (check_col(pinfo->cinfo, COL_INFO)) 
1440                 col_set_str(pinfo->cinfo, COL_INFO, "OAMPDU: Event Notification");
1441             break;
1442         case OAMPDU_VAR_REQUEST:
1443             if (check_col(pinfo->cinfo, COL_INFO)) 
1444                 col_set_str(pinfo->cinfo, COL_INFO, "OAMPDU: Variable Request");
1445             break;
1446         case OAMPDU_VAR_RESPONSE:
1447             if (check_col(pinfo->cinfo, COL_INFO)) 
1448                 col_set_str(pinfo->cinfo, COL_INFO, "OAMPDU: Variable Response");
1449             break;
1450         case OAMPDU_LOOPBACK_CTRL:
1451             if (check_col(pinfo->cinfo, COL_INFO)) 
1452                 col_set_str(pinfo->cinfo, COL_INFO, "OAMPDU: Loopback Control");
1453             break;
1454         case OAMPDU_VENDOR_SPECIFIC:
1455             if (check_col(pinfo->cinfo, COL_INFO)) 
1456                 col_set_str(pinfo->cinfo, COL_INFO, "OAMPDU: Organization Specific");
1457             break;
1458         default:
1459             if (check_col(pinfo->cinfo, COL_INFO)) 
1460                 col_set_str(pinfo->cinfo, COL_INFO, "OAMPDU reserved");
1461             break;
1462     }
1463
1464
1465     if (tree)
1466     {
1467         /* Add OAM Heading */
1468         oampdu_item = proto_tree_add_protocol_format(tree, proto_slow, tvb,
1469                 0, -1, "OAM Protocol");
1470         oampdu_tree = proto_item_add_subtree(oampdu_item, ett_oampdu);
1471
1472         /* Subtype */
1473         proto_tree_add_item(oampdu_tree, hf_slow_subtype, tvb,
1474                 0, 1, FALSE);
1475
1476         /* Flags field */
1477         flags = tvb_get_ntohs(tvb, OAMPDU_FLAGS);
1478         flags_item = proto_tree_add_uint(oampdu_tree, hf_oampdu_flags, tvb,
1479                 OAMPDU_FLAGS, 2, flags);
1480         flags_tree = proto_item_add_subtree(flags_item, ett_oampdu_flags);
1481
1482         /*
1483          * In this section we add keywords for the bit set on the Flags's line.
1484          * We also add all the bit inside the subtree.
1485          */
1486         APPEND_BOOLEAN_FLAG(flags & OAMPDU_FLAGS_LINK_FAULT, flags_item,
1487                 "%sLink Fault");
1488         proto_tree_add_boolean(flags_tree, hf_oampdu_flags_link_fault,
1489                 tvb, OAMPDU_FLAGS, 1, flags);
1490
1491         APPEND_BOOLEAN_FLAG(flags & OAMPDU_FLAGS_DYING_GASP, flags_item,
1492                 "%sDying Gasp");
1493         proto_tree_add_boolean(flags_tree, hf_oampdu_flags_dying_gasp,
1494                 tvb, OAMPDU_FLAGS, 1, flags);
1495
1496         APPEND_BOOLEAN_FLAG(flags & OAMPDU_FLAGS_CRITICAL_EVENT, flags_item,
1497                 "%sCriticalEvent");
1498         proto_tree_add_boolean(flags_tree, hf_oampdu_flags_critical_event,
1499                 tvb, OAMPDU_FLAGS, 1, flags);
1500
1501         proto_tree_add_boolean(flags_tree, hf_oampdu_flags_local_evaluating,
1502                 tvb, OAMPDU_FLAGS, 1, flags);
1503
1504         proto_tree_add_boolean(flags_tree, hf_oampdu_flags_local_stable,
1505                 tvb, OAMPDU_FLAGS, 1, flags);
1506
1507         proto_tree_add_boolean(flags_tree, hf_oampdu_flags_remote_evaluating,
1508                 tvb, OAMPDU_FLAGS, 1, flags);
1509
1510         proto_tree_add_boolean(flags_tree, hf_oampdu_flags_remote_stable,
1511                 tvb, OAMPDU_FLAGS, 1, flags);
1512
1513         if (sep != cont_sep)
1514             proto_item_append_text(flags_item, " (");
1515         else
1516             proto_item_append_text(flags_item, ", ");
1517         
1518         for(i=0;i<2;i++)
1519         {
1520             if (i==0)
1521             {
1522                 proto_item_append_text(flags_item, "local: ");
1523                 state = (flags&(OAMPDU_FLAGS_LOCAL_EVAL|OAMPDU_FLAGS_LOCAL_STABLE));
1524                 state = state>>3;
1525             }
1526             else
1527             {
1528                 proto_item_append_text(flags_item, "remote: ");
1529                 state = (flags&(OAMPDU_FLAGS_REMOTE_EVAL|OAMPDU_FLAGS_REMOTE_STABLE));
1530                 state = state>>5;
1531             }
1532             
1533             switch (state)
1534             {
1535                 case 0:
1536                     proto_item_append_text(flags_item, "Unsatisfied");
1537                     break;
1538                 case 1:
1539                     proto_item_append_text(flags_item, "Discovery in process");
1540                     break;
1541                 case 2:
1542                     proto_item_append_text(flags_item, "Discovery complete");
1543                     break;
1544                 default:
1545                     proto_item_append_text(flags_item, "Reserved");
1546                     break;
1547             }
1548
1549             if (i==0)     
1550                 proto_item_append_text(flags_item, ", ");
1551
1552         }        
1553
1554         proto_item_append_text(flags_item, ")");
1555
1556         /* OAMPDU code */
1557         oampdu_code = tvb_get_guint8(tvb, OAMPDU_CODE);
1558         proto_tree_add_uint(oampdu_tree, hf_oampdu_code, tvb,
1559                 OAMPDU_CODE, 1, oampdu_code);
1560
1561         switch (oampdu_code)
1562         {
1563             case OAMPDU_INFORMATION:
1564                 dissect_oampdu_information(tvb, oampdu_tree);
1565                 break;
1566             case OAMPDU_EVENT_NOTIFICATION:
1567                 dissect_oampdu_event_notification(tvb, oampdu_tree);
1568                 break;
1569             case OAMPDU_VAR_REQUEST:
1570                 dissect_oampdu_variable_request(tvb, oampdu_tree);
1571                 break;
1572             case OAMPDU_VAR_RESPONSE:
1573                 dissect_oampdu_variable_response(tvb, oampdu_tree);
1574                 break;
1575             case OAMPDU_LOOPBACK_CTRL:
1576                 dissect_oampdu_loopback_control(tvb, oampdu_tree);
1577                 break;
1578             case OAMPDU_VENDOR_SPECIFIC:
1579                 dissect_oampdu_vendor_specific(tvb, oampdu_tree);
1580             default:
1581                 break;
1582         }
1583     }
1584 }
1585
1586 /*
1587  * Name: dissect_oampdu_information
1588  *
1589  * Description:
1590  *    This function is used to dissect the Information TLVs define in IEEE802.3
1591  *    section 57.5.2).
1592  *
1593  *
1594  * Input Arguments:
1595  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
1596  *    tree: the protocol tree associate with the oampdu (see proto.h).
1597  *
1598  * Return Values: None
1599  *
1600  * Notes:
1601  *    Dominique Bastien (dbastien@accedian.com)
1602  *      + add support for 802.3ah-2004.
1603  */
1604 static void
1605 dissect_oampdu_information(tvbuff_t *tvb, proto_tree *tree)
1606 {
1607       guint16   raw_word;
1608       guint8    raw_octet;
1609       guint8    info_type;
1610       guint32   offset;
1611       guint16   bytes;
1612
1613       const guint8 *resv_bytes;
1614       const guint8 *ptr;
1615
1616       proto_tree *info_tree;
1617       proto_item *info_item;
1618       proto_tree *state_tree;
1619       proto_item *state_item;
1620       proto_tree *cfg_tree;
1621       proto_item *cfg_item;
1622       proto_item *oui_item;
1623       proto_item *item;
1624
1625
1626       offset = OAMPDU_HEADER_SIZE;
1627
1628       bytes = tvb_length_remaining(tvb, offset);
1629
1630       while (1)
1631       {
1632         bytes = tvb_length_remaining(tvb, offset);
1633         if (bytes < 1) break;
1634
1635         info_type = tvb_get_guint8(tvb, offset);
1636
1637         if (info_type == OAMPDU_INFO_TYPE_ENDMARKER) break;
1638
1639         info_item = proto_tree_add_uint(tree, hf_oampdu_info_type, tvb,
1640                             offset, 1, info_type);
1641
1642         switch (info_type)
1643         {
1644          case OAMPDU_INFO_TYPE_LOCAL:
1645            info_tree = proto_item_add_subtree(info_item, ett_oampdu_local_info);
1646            break;
1647          case OAMPDU_INFO_TYPE_REMOTE:
1648            info_tree = proto_item_add_subtree(info_item, ett_oampdu_remote_info);
1649            break;
1650          case OAMPDU_INFO_TYPE_ORG:
1651            info_tree = proto_item_add_subtree(info_item, ett_oampdu_org_info);
1652            break;
1653          default:
1654             info_tree = NULL;
1655            break;
1656         }
1657
1658         offset += OAMPDU_INFO_TYPE_SZ;
1659
1660         if ((info_type==OAMPDU_INFO_TYPE_LOCAL)||(info_type==OAMPDU_INFO_TYPE_REMOTE))
1661         {
1662             raw_octet = tvb_get_guint8(tvb, offset);
1663             proto_tree_add_uint(info_tree, hf_oampdu_info_len,
1664                     tvb, offset, 1, raw_octet);
1665
1666             offset += OAMPDU_INFO_LENGTH_SZ;
1667
1668             raw_octet = tvb_get_guint8(tvb, offset);
1669             proto_tree_add_uint(info_tree, hf_oampdu_info_version,
1670                     tvb, offset, 1, raw_octet);
1671
1672             offset += OAMPDU_INFO_VERSION_SZ;
1673
1674             raw_word = tvb_get_ntohs(tvb, offset);
1675             proto_tree_add_uint(info_tree, hf_oampdu_info_revision,
1676                     tvb, offset, 2, raw_word);
1677
1678             offset += OAMPDU_INFO_REVISION_SZ;
1679
1680             /* Build OAM State field field */
1681             raw_octet = tvb_get_guint8(tvb, offset);
1682             state_item = proto_tree_add_uint(info_tree, hf_oampdu_info_state,
1683                     tvb, offset, 1, raw_octet);
1684
1685             if (raw_octet == OAMPDU_INFO_TYPE_LOCAL)
1686                 state_tree = proto_item_add_subtree(state_item, ett_oampdu_local_info_state);
1687             else
1688                 state_tree = proto_item_add_subtree(state_item, ett_oampdu_remote_info_state);
1689
1690             proto_tree_add_uint(state_tree, hf_oampdu_info_state_parser,
1691                     tvb, offset, 1, raw_octet);
1692
1693             proto_tree_add_boolean(state_tree, hf_oampdu_info_state_mux,
1694                     tvb, offset, 1, raw_octet);
1695
1696             offset += OAMPDU_INFO_STATE_SZ;
1697
1698             /* Build OAM configuration field */
1699             raw_octet = tvb_get_guint8(tvb, offset);
1700             cfg_item = proto_tree_add_uint(info_tree, hf_oampdu_info_oamConfig,
1701                     tvb, offset, 1, raw_octet);
1702
1703             if (raw_octet == OAMPDU_INFO_TYPE_LOCAL)
1704                 cfg_tree = proto_item_add_subtree(cfg_item, ett_oampdu_local_info_config);
1705             else
1706                 cfg_tree = proto_item_add_subtree(cfg_item, ett_oampdu_remote_info_config);
1707
1708             proto_tree_add_boolean(cfg_tree, hf_oampdu_info_oamConfig_mode,
1709                     tvb, offset, 1, raw_octet);
1710
1711             proto_tree_add_boolean(cfg_tree, hf_oampdu_info_oamConfig_uni,
1712                     tvb, offset, 1, raw_octet);
1713
1714             proto_tree_add_boolean(cfg_tree, hf_oampdu_info_oamConfig_lpbk,
1715                     tvb, offset, 1, raw_octet);
1716
1717             proto_tree_add_boolean(cfg_tree, hf_oampdu_info_oamConfig_event,
1718                     tvb, offset, 1, raw_octet);
1719
1720             proto_tree_add_boolean(cfg_tree, hf_oampdu_info_oamConfig_var,
1721                     tvb, offset, 1, raw_octet);
1722
1723             offset += OAMPDU_INFO_OAM_CONFIG_SZ;
1724
1725             raw_word = tvb_get_ntohs(tvb, offset);
1726             item = proto_tree_add_uint(info_tree, hf_oampdu_info_oampduConfig,
1727                     tvb, offset, 2, raw_word);
1728
1729             proto_item_append_text(item, " (bytes)");
1730
1731             offset += OAMPDU_INFO_OAMPDU_CONFIG_SZ;
1732
1733             resv_bytes = tvb_get_ptr(tvb, offset, 3);
1734             oui_item = proto_tree_add_bytes(info_tree, hf_oampdu_info_oui,
1735                     tvb, offset, 3, resv_bytes);
1736
1737             APPEND_OUI_NAME(oui_item, ptr, resv_bytes);
1738
1739             offset += OAMPDU_INFO_OUI_SZ;
1740
1741             resv_bytes = tvb_get_ptr(tvb, offset, 4);
1742             proto_tree_add_bytes(info_tree, hf_oampdu_info_vendor,
1743                     tvb, offset, 4, resv_bytes);
1744   
1745             offset += OAMPDU_INFO_VENDOR_SPECIFIC_SZ;
1746          }
1747          else if (info_type == OAMPDU_INFO_TYPE_ORG)
1748          {
1749             /* see IEEE802.3, section 57.5.2.3 for more details */
1750             raw_octet = tvb_get_guint8(tvb, offset);
1751             proto_tree_add_uint(info_tree, hf_oampdu_info_len,
1752                     tvb, offset, 1, raw_octet);
1753
1754             offset += OAMPDU_INFO_LENGTH_SZ;
1755
1756             resv_bytes = tvb_get_ptr(tvb, offset, 3);
1757             oui_item = proto_tree_add_bytes(info_tree, hf_oampdu_info_oui,
1758                     tvb, offset, 3, resv_bytes);
1759
1760             APPEND_OUI_NAME(oui_item, ptr, resv_bytes);
1761
1762             offset += OAMPDU_INFO_OUI_SZ;
1763
1764             resv_bytes = tvb_get_ptr(tvb, offset, raw_octet-5);
1765             proto_tree_add_bytes(info_tree, hf_oampdu_info_vendor,
1766                     tvb, offset, raw_octet-5, resv_bytes);
1767
1768             offset += raw_octet-2;
1769
1770          }
1771          else if (info_type==OAMPDU_INFO_TYPE_ENDMARKER)
1772          {
1773            /* A TLV of zero indicate an End of TLV marker */
1774            break;
1775          }
1776          else
1777          {
1778             /* If it's a unknown type jump over */
1779             raw_octet = tvb_get_guint8(tvb, offset);
1780             offset += raw_octet;
1781          }
1782       }
1783 }
1784
1785 /*
1786  * Name: dissect_oampdu_event_notification
1787  *
1788  * Description:
1789  *    This function is used to dissect the Event Notification TLVs define in
1790  *    IEEE802.3 section 57.5.3).
1791  *
1792  *
1793  * Input Arguments:
1794  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
1795  *    tree: the protocol tree associate with the oampdu (see proto.h).
1796  *
1797  * Return Values: None
1798  *
1799  * Notes:
1800  *    Dominique Bastien (dbastien@accedian.com)
1801  *      + add support for 802.3ah-2004.
1802  */
1803 static void
1804 dissect_oampdu_event_notification(tvbuff_t *tvb, proto_tree *tree)
1805 {
1806     guint8    raw_octet;
1807     guint16   raw_word;
1808     guint32   dword;
1809     guint64   big;
1810
1811     guint8    event_type;
1812     guint32   offset;
1813     guint16   bytes;
1814
1815     proto_tree *event_tree;
1816     proto_item *event_item;
1817
1818     offset = OAMPDU_HEADER_SIZE;
1819
1820     /* Display the sequence number before displaying the TLVs */
1821     raw_word = tvb_get_ntohs(tvb, offset);
1822     proto_tree_add_uint(tree, hf_oampdu_event_sequence,
1823             tvb, offset, 2, raw_word);
1824
1825     offset += OAMPDU_EVENT_SEQUENCE_SZ;
1826
1827     while (1)
1828     {
1829         bytes = tvb_length_remaining(tvb, offset);
1830         if (bytes < 1) break;
1831
1832         event_type = tvb_get_guint8(tvb, offset);
1833
1834         if (event_type == 0) break;
1835
1836         event_item = proto_tree_add_uint(tree, hf_oampdu_event_type,
1837                             tvb, offset, 1, event_type);
1838
1839         offset += OAMPDU_EVENT_TYPE_SZ;
1840
1841         switch (event_type)
1842         {
1843             case OAMPDU_EVENT_TYPE_END:
1844                 break; 
1845             case OAMPDU_EVENT_TYPE_ESPE: 
1846             {
1847                 event_tree = proto_item_add_subtree(event_item,
1848                                     ett_oampdu_event_espe);
1849
1850                 raw_octet = tvb_get_guint8(tvb, offset);
1851                 proto_tree_add_uint(event_tree, hf_oampdu_event_length,
1852                         tvb, offset, 1, raw_octet);
1853
1854                 offset += OAMPDU_EVENT_LENGTH_SZ;
1855
1856                 raw_word = tvb_get_ntohs(tvb, offset);
1857                 proto_tree_add_uint(event_tree, hf_oampdu_event_timeStamp,
1858                         tvb, offset, 2, raw_word);
1859
1860                 offset += OAMPDU_EVENT_TIMESTAMP_SZ;
1861
1862                 big = tvb_get_ntoh64(tvb, offset);
1863                 proto_tree_add_uint64(event_tree, hf_oampdu_event_espeWindow,
1864                         tvb, offset, 8, big);
1865
1866                 offset += OAMPDU_ESPE_WINDOW_SZ;
1867
1868                 big = tvb_get_ntoh64(tvb, offset);
1869                 proto_tree_add_uint64(event_tree, hf_oampdu_event_espeThreshold,
1870                         tvb, offset, 8, big);
1871
1872                 offset += OAMPDU_ESPE_THRESHOLD_SZ;
1873
1874                 big = tvb_get_ntoh64(tvb, offset);
1875                 proto_tree_add_uint64(event_tree, hf_oampdu_event_espeErrors,
1876                         tvb, offset, 8, big);
1877
1878                 offset += OAMPDU_ESPE_ERRORS_SZ;
1879
1880                 big = tvb_get_ntoh64(tvb, offset);
1881                 proto_tree_add_uint64(event_tree, hf_oampdu_event_espeTotalErrors,
1882                         tvb, offset, 8, big);
1883
1884                 offset += OAMPDU_ESPE_ERR_TOTAL_SZ;
1885
1886                 dword = tvb_get_ntohl(tvb, offset);
1887                 proto_tree_add_uint(event_tree, hf_oampdu_event_espeTotalEvents,
1888                         tvb, offset, 4, dword);
1889
1890                 offset += OAMPDU_ESPE_TOTAL_SZ;
1891                 break;
1892             }
1893             case OAMPDU_EVENT_TYPE_EFE:  
1894             {
1895                 event_tree = proto_item_add_subtree(event_item,
1896                                     ett_oampdu_event_efe);
1897
1898                 raw_octet = tvb_get_guint8(tvb, offset);
1899                 proto_tree_add_uint(event_tree, hf_oampdu_event_length,
1900                         tvb, offset, 1, raw_octet);
1901
1902                 offset += OAMPDU_EVENT_LENGTH_SZ;
1903
1904                 raw_word = tvb_get_ntohs(tvb, offset);
1905                 proto_tree_add_uint(event_tree, hf_oampdu_event_timeStamp,
1906                         tvb, offset, 2, raw_word);
1907
1908                 offset += OAMPDU_EVENT_TIMESTAMP_SZ;
1909
1910                 raw_word = tvb_get_ntohs(tvb, offset);
1911                 proto_tree_add_uint(event_tree, hf_oampdu_event_efeWindow,
1912                         tvb, offset, 2, raw_word);
1913
1914                 offset += OAMPDU_EFE_WINDOW_SZ;
1915
1916                 dword = tvb_get_ntohl(tvb, offset);
1917                 proto_tree_add_uint(event_tree, hf_oampdu_event_efeThreshold,
1918                         tvb, offset, 4, dword);
1919
1920                 offset += OAMPDU_EFE_THRESHOLD_SZ;
1921
1922                 dword = tvb_get_ntohl(tvb, offset);
1923                 proto_tree_add_uint(event_tree, hf_oampdu_event_efeErrors,
1924                         tvb, offset, 4, dword);
1925
1926                 offset += OAMPDU_EFE_ERRORS_SZ;
1927
1928                 big = tvb_get_ntoh64(tvb, offset);
1929                 proto_tree_add_uint64(event_tree, hf_oampdu_event_efeTotalErrors,
1930                         tvb, offset, 8, big);
1931
1932                 offset += OAMPDU_EFE_ERR_TOTAL_SZ;
1933
1934                 dword = tvb_get_ntohl(tvb, offset);
1935                 proto_tree_add_uint(event_tree, hf_oampdu_event_efeTotalEvents,
1936                         tvb, offset, 4, dword);
1937
1938                 offset += OAMPDU_EFE_TOTAL_SZ;
1939
1940                 break;
1941             }
1942             case OAMPDU_EVENT_TYPE_EFPE: 
1943             {
1944                 event_tree = proto_item_add_subtree(event_item,
1945                                     ett_oampdu_event_efpe);
1946
1947                 raw_octet = tvb_get_guint8(tvb, offset);
1948                 proto_tree_add_uint(event_tree, hf_oampdu_event_length,
1949                         tvb, offset, 1, raw_octet);
1950
1951                 offset += OAMPDU_EVENT_LENGTH_SZ;
1952
1953                 raw_word = tvb_get_ntohs(tvb, offset);
1954                 proto_tree_add_uint(event_tree, hf_oampdu_event_timeStamp,
1955                         tvb, offset, 2, raw_word);
1956
1957                 offset += OAMPDU_EVENT_TIMESTAMP_SZ;
1958
1959                 raw_word = tvb_get_ntohl(tvb, offset);
1960                 proto_tree_add_uint(event_tree, hf_oampdu_event_efpeWindow,
1961                         tvb, offset, 4, raw_word);
1962
1963                 offset += OAMPDU_EFPE_WINDOW_SZ;
1964
1965                 dword = tvb_get_ntohl(tvb, offset);
1966                 proto_tree_add_uint(event_tree, hf_oampdu_event_efpeThreshold,
1967                         tvb, offset, 4, dword);
1968
1969                 offset += OAMPDU_EFPE_THRESHOLD_SZ;
1970
1971                 dword = tvb_get_ntohl(tvb, offset);
1972                 proto_tree_add_uint(event_tree, hf_oampdu_event_efpeErrors,
1973                         tvb, offset, 4, dword);
1974
1975                 offset += OAMPDU_EFPE_ERRORS_SZ;
1976
1977                 big = tvb_get_ntoh64(tvb, offset);
1978                 proto_tree_add_uint64(event_tree, hf_oampdu_event_efpeTotalErrors,
1979                         tvb, offset, 8, big);
1980
1981                 offset += OAMPDU_EFPE_ERR_TOTAL_SZ;
1982
1983                 dword = tvb_get_ntohl(tvb, offset);
1984                 proto_tree_add_uint(event_tree, hf_oampdu_event_efpeTotalEvents,
1985                         tvb, offset, 4, dword);
1986
1987                 offset += OAMPDU_EFPE_TOTAL_SZ;
1988
1989                 break;
1990             }
1991             case OAMPDU_EVENT_TYPE_EFSSE:
1992             {
1993                 event_tree = proto_item_add_subtree(event_item,
1994                                     ett_oampdu_event_efsse);
1995
1996                 raw_octet = tvb_get_guint8(tvb, offset);
1997                 proto_tree_add_uint(event_tree, hf_oampdu_event_length,
1998                         tvb, offset, 1, raw_octet);
1999
2000                 offset += OAMPDU_EVENT_LENGTH_SZ;
2001
2002                 raw_word = tvb_get_ntohs(tvb, offset);
2003                 proto_tree_add_uint(event_tree, hf_oampdu_event_timeStamp,
2004                         tvb, offset, 2, raw_word);
2005
2006                 offset += OAMPDU_EVENT_TIMESTAMP_SZ;
2007
2008                 raw_word = tvb_get_ntohs(tvb, offset);
2009                 proto_tree_add_uint(event_tree, hf_oampdu_event_efsseWindow,
2010                         tvb, offset, 2, raw_word);
2011
2012                 offset += OAMPDU_EFSSE_WINDOW_SZ;
2013
2014                 dword = tvb_get_ntohs(tvb, offset);
2015                 proto_tree_add_uint(event_tree, hf_oampdu_event_efsseThreshold,
2016                         tvb, offset, 2, dword);
2017
2018                 offset += OAMPDU_EFSSE_THRESHOLD_SZ;
2019
2020                 dword = tvb_get_ntohs(tvb, offset);
2021                 proto_tree_add_uint(event_tree, hf_oampdu_event_efsseErrors,
2022                         tvb, offset, 2, dword);
2023
2024                 offset += OAMPDU_EFSSE_ERRORS_SZ;
2025
2026                 dword = tvb_get_ntohl(tvb, offset);
2027                 proto_tree_add_uint(event_tree, hf_oampdu_event_efsseTotalErrors,
2028                         tvb, offset, 4, dword);
2029
2030                 offset += OAMPDU_EFSSE_ERR_TOTAL_SZ;
2031
2032                 dword = tvb_get_ntohl(tvb, offset);
2033                 proto_tree_add_uint(event_tree, hf_oampdu_event_efsseTotalEvents,
2034                         tvb, offset, 4, dword);
2035
2036                 offset += OAMPDU_EFSSE_TOTAL_SZ;
2037
2038                 break;
2039             }
2040             case OAMPDU_EVENT_TYPE_OSE:
2041             {
2042                 event_tree = proto_item_add_subtree(event_item,
2043                                     ett_oampdu_event_ose);
2044
2045                 raw_octet = tvb_get_guint8(tvb, offset);
2046                 proto_tree_add_uint(event_tree, hf_oampdu_event_length,
2047                         tvb, offset, 1, raw_octet);
2048
2049                 offset += OAMPDU_EVENT_LENGTH_SZ;
2050
2051                 offset += (raw_word-2);
2052                 break;
2053             }
2054             default:
2055               break;
2056         }
2057     }
2058 }
2059
2060 /*
2061  * Name: dissect_oampdu_variable_request
2062  *
2063  * Description:
2064  *    This function is used to dissect the Variable Request TLVs define in
2065  *    IEEE802.3 section 57.6).
2066  *
2067  *
2068  * Input Arguments:
2069  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
2070  *    tree: the protocol tree associate with the oampdu (see proto.h).
2071  *
2072  * Return Values: None
2073  *
2074  * Notes:
2075  *    Dominique Bastien (dbastien@accedian.com)
2076  *      + add support for 802.3ah-2004.
2077  */
2078 static void
2079 dissect_oampdu_variable_request(tvbuff_t *tvb, proto_tree *tree)
2080 {
2081     guint16   raw_word;
2082     guint8    raw_octet;
2083     guint32   offset;
2084
2085
2086     offset = OAMPDU_HEADER_SIZE;
2087
2088     while (1)
2089     {
2090         raw_octet = tvb_get_guint8(tvb, offset);
2091
2092         if (raw_octet == 0) break;
2093
2094         proto_tree_add_uint(tree, hf_oampdu_variable_branch,
2095                 tvb,offset, 1, raw_octet);
2096
2097         offset+=1;
2098
2099         switch (raw_octet)
2100         {
2101             case OAMPDU_VARS_OBJECT:
2102             {
2103                 raw_word = tvb_get_ntohs(tvb, offset);
2104                 proto_tree_add_uint(tree, hf_oampdu_variable_object,
2105                         tvb, offset, 2, raw_word);
2106                 break;
2107             }
2108             case OAMPDU_VARS_PACKAGE:
2109             {
2110                 raw_word = tvb_get_ntohs(tvb, offset);
2111                 proto_tree_add_uint(tree, hf_oampdu_variable_package,
2112                         tvb, offset, 2, raw_word);
2113                 break;
2114             }
2115             case OAMPDU_VARS_BINDING:
2116             {
2117                 raw_word = tvb_get_ntohs(tvb, offset);
2118                 proto_tree_add_uint(tree, hf_oampdu_variable_binding,
2119                         tvb, offset, 2, raw_word);
2120                 break;
2121             }
2122             case OAMPDU_VARS_ATTRIBUTE:
2123             {
2124                 raw_word = tvb_get_ntohs(tvb, offset);
2125                 proto_tree_add_uint(tree, hf_oampdu_variable_attribute,
2126                         tvb, offset, 2, raw_word);
2127                 break;
2128             }
2129             default:
2130                 break;
2131         }
2132
2133         offset+=2;
2134     }
2135 }
2136
2137 /*
2138  * Name: dissect_oampdu_variable_response
2139  *
2140  * Description:
2141  *    This function is used to dissect the Variable Response TLVs define in
2142  *    IEEE802.3 section 57.6).
2143  *
2144  *
2145  * Input Arguments:
2146  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
2147  *    tree: the protocol tree associate with the oampdu (see proto.h).
2148  *
2149  * Return Values: None
2150  *
2151  * Notes:
2152  *    Dominique Bastien (dbastien@accedian.com)
2153  *      + add support for 802.3ah-2004.
2154  */
2155 static void
2156 dissect_oampdu_variable_response(tvbuff_t *tvb, proto_tree *tree)
2157 {
2158       guint16   raw_word;
2159       guint8    raw_octet;
2160       guint32   offset;
2161
2162       const guint8 *resv_bytes;
2163
2164
2165       offset = OAMPDU_HEADER_SIZE;
2166
2167       while (1)
2168       {
2169         raw_octet = tvb_get_guint8(tvb, offset);
2170
2171         if (raw_octet == 0) break;
2172
2173         proto_tree_add_uint(tree, hf_oampdu_variable_branch,
2174                 tvb,offset, 1, raw_octet);
2175
2176         offset+=1;
2177
2178         switch (raw_octet)
2179         {
2180             case OAMPDU_VARS_OBJECT:
2181             {
2182                 raw_word = tvb_get_ntohs(tvb, offset);
2183                 proto_tree_add_uint(tree, hf_oampdu_variable_object,
2184                         tvb, offset, 2, raw_word);
2185                 break;
2186             }
2187             case OAMPDU_VARS_PACKAGE:
2188             {
2189                 raw_word = tvb_get_ntohs(tvb, offset);
2190                 proto_tree_add_uint(tree, hf_oampdu_variable_package,
2191                         tvb, offset, 2, raw_word);
2192                 break;
2193             }
2194             case OAMPDU_VARS_BINDING:
2195             {
2196                 raw_word = tvb_get_ntohs(tvb, offset);
2197                 proto_tree_add_uint(tree, hf_oampdu_variable_binding,
2198                         tvb, offset, 2, raw_word);
2199                 break;
2200             }
2201             case OAMPDU_VARS_ATTRIBUTE:
2202             {
2203                 raw_word = tvb_get_ntohs(tvb, offset);
2204                 proto_tree_add_uint(tree, hf_oampdu_variable_attribute,
2205                         tvb, offset, 2, raw_word);
2206                 break;
2207             }
2208             default:
2209                 break;
2210         }
2211
2212         offset+=2;
2213
2214         raw_octet = tvb_get_guint8(tvb, offset);
2215
2216         if (raw_octet >= 0x80)
2217         {
2218             /* Variable Indication */
2219             proto_tree_add_uint(tree, hf_oampdu_variable_indication,
2220                     tvb,offset, 1, (raw_octet&0x7F));
2221
2222             offset+=1;
2223         }
2224         else 
2225         {
2226             /* Special case for 128 bytes container */
2227             if (raw_octet == 0) raw_octet = 128;
2228
2229             proto_tree_add_uint(tree, hf_oampdu_variable_width,
2230                     tvb,offset, 1, raw_octet);
2231
2232             offset+=1;
2233
2234             resv_bytes = tvb_get_ptr(tvb, offset, raw_octet);
2235             proto_tree_add_bytes(tree, hf_oampdu_variable_value,
2236                     tvb, offset, raw_octet, resv_bytes);
2237
2238             offset+=raw_octet;        
2239         }
2240       }
2241 }
2242
2243 /*
2244  * Name: dissect_oampdu_loopback_control
2245  *
2246  * Description:
2247  *    This function is used to dissect the Variable Request TLVs define in
2248  *    IEEE802.3 section 57.6).
2249  *
2250  *
2251  * Input Arguments:
2252  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
2253  *    tree: the protocol tree associate with the oampdu (see proto.h).
2254  *
2255  * Return Values: None
2256  *
2257  * Notes:
2258  *    Dominique Bastien (dbastien@accedian.com)
2259  *      + add support for 802.3ah-2004.
2260  */
2261 static void
2262 dissect_oampdu_loopback_control(tvbuff_t *tvb, proto_tree *tree)
2263 {
2264     guint8    ctrl;
2265     guint32   offset;
2266     guint16   bytes;
2267
2268     proto_tree *ctrl_tree;
2269     proto_item *ctrl_item;
2270
2271     const char *sep;
2272
2273     offset = OAMPDU_HEADER_SIZE;
2274
2275     bytes = tvb_length_remaining(tvb, offset);
2276
2277     if (bytes >= 1)
2278     {
2279         ctrl = tvb_get_guint8(tvb, offset);
2280
2281         ctrl_item = proto_tree_add_uint(tree, hf_oampdu_lpbk,
2282                             tvb, offset, 1, ctrl);
2283
2284         ctrl_tree = proto_item_add_subtree(ctrl_item, ett_oampdu_lpbk_ctrl);
2285
2286         sep = initial_sep;
2287
2288         APPEND_BOOLEAN_FLAG(ctrl & OAMPDU_LPBK_ENABLE, ctrl_item,
2289                 "%sEnable Remote Loopack");
2290         proto_tree_add_boolean(ctrl_tree, hf_oampdu_lpbk_enable,
2291                 tvb, offset, 1, ctrl);
2292
2293         APPEND_BOOLEAN_FLAG(ctrl & OAMPDU_LPBK_DISABLE, ctrl_item,
2294                 "%sDisable Remote Loopback");
2295         proto_tree_add_boolean(ctrl_tree, hf_oampdu_lpbk_disable,
2296                 tvb, offset, 1, ctrl);
2297
2298         if (sep != initial_sep)
2299             proto_item_append_text(ctrl_item, ")");
2300     }
2301 }
2302
2303 /*
2304  * Name: dissect_oampdu_vendor_specific
2305  *
2306  * Description:
2307  *    This function is used to dissect the Vendor Specific TLV define in
2308  *    IEEE802.3 section 57.4.3.6).
2309  *
2310  *
2311  * Input Arguments:
2312  *    tvb: buffer associate with the rcv packet (see tvbuff.h).
2313  *    tree: the protocol tree associate with the oampdu (see proto.h).
2314  *
2315  * Return Values: None
2316  *
2317  * Notes:
2318  *    Dominique Bastien (dbastien@accedian.com)
2319  *      + add support for 802.3ah-2004.
2320  */
2321 static void
2322 dissect_oampdu_vendor_specific(tvbuff_t *tvb, proto_tree *tree)
2323 {
2324     guint32   offset;
2325     guint16   bytes;
2326
2327     const guint8 *resv_bytes;
2328     const guint8 *ptr;
2329
2330     proto_item *oui_item;
2331
2332
2333     offset = OAMPDU_HEADER_SIZE;
2334
2335     bytes = tvb_length_remaining(tvb, offset);
2336
2337     if (bytes >= 3)
2338     {
2339         resv_bytes = tvb_get_ptr(tvb, offset, 3);
2340         oui_item = proto_tree_add_bytes(tree, hf_oampdu_info_oui,
2341                                         tvb, offset, 3, resv_bytes);
2342
2343         APPEND_OUI_NAME(oui_item, ptr, resv_bytes);
2344     }
2345 }
2346
2347
2348 /* Register the protocol with Wireshark */
2349 void
2350 proto_register_slow_protocols(void)
2351 {
2352 /* Setup list of header fields */
2353
2354   static hf_register_info hf[] = {
2355
2356 /*
2357  * Generic slow protocol portion
2358  */
2359     { &hf_slow_subtype,
2360       { "Slow Protocols subtype",    "slow.subtype",
2361          FT_UINT8,    BASE_HEX,    VALS(subtype_vals),    0x0,
2362         "Identifies the LACP version", HFILL }},
2363
2364 /*
2365  *  LACP portion
2366  */
2367     { &hf_lacpdu_version_number,
2368       { "LACP Version Number",    "slow.lacp.version",
2369          FT_UINT8,    BASE_HEX,    NULL,    0x0,
2370         "Identifies the LACP version", HFILL }},
2371
2372     { &hf_lacpdu_actor_type,
2373       { "Actor Information",    "slow.lacp.actorInfo",
2374         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2375         "TLV type = Actor", HFILL }},
2376
2377     { &hf_lacpdu_actor_info_len,
2378       { "Actor Information Length",            "slow.lacp.actorInfoLen",
2379         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2380         "The length of the Actor TLV", HFILL }},
2381
2382     { &hf_lacpdu_actor_sys_priority,
2383       { "Actor System Priority",  "slow.lacp.actorSysPriority",
2384         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2385         "The priority assigned to this System by management or admin", HFILL }},
2386
2387     { &hf_lacpdu_actor_sys,
2388       { "Actor System",            "slow.lacp.actorSystem",
2389         FT_ETHER,    BASE_NONE,    NULL,    0x0,
2390         "The Actor's System ID encoded as a MAC address", HFILL }},
2391
2392     { &hf_lacpdu_actor_key,
2393       { "Actor Key",            "slow.lacp.actorKey",
2394         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2395         "The operational Key value assigned to the port by the Actor", HFILL }},
2396
2397     { &hf_lacpdu_actor_port_priority,
2398       { "Actor Port Priority",            "slow.lacp.actorPortPriority",
2399         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2400         "The priority assigned to the port by the Actor (via Management or Admin)", HFILL }},
2401
2402     { &hf_lacpdu_actor_port,
2403       { "Actor Port",            "slow.lacp.actorPort",
2404         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2405         "The port number assigned to the port by the Actor (via Management or Admin)", HFILL }},
2406
2407     { &hf_lacpdu_actor_state,
2408       { "Actor State",            "slow.lacp.actorState",
2409         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2410         "The Actor's state variables for the port, encoded as bits within a single octet", HFILL }},
2411
2412     { &hf_lacpdu_flags_a_activity,
2413       { "LACP Activity",        "slow.lacp.actorState.activity",
2414         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_ACTIVITY,
2415         "Activity control value for this link. Active = 1, Passive = 0", HFILL }},
2416
2417     { &hf_lacpdu_flags_a_timeout,
2418       { "LACP Timeout",        "slow.lacp.actorState.timeout",
2419         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_TIMEOUT,
2420         "Timeout control value for this link. Short Timeout = 1, Long Timeout = 0", HFILL }},
2421
2422     { &hf_lacpdu_flags_a_aggregation,
2423       { "Aggregation",        "slow.lacp.actorState.aggregation",
2424         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_AGGREGATION,
2425         "Aggregatable = 1, Individual = 0", HFILL }},
2426
2427     { &hf_lacpdu_flags_a_sync,
2428       { "Synchronization",        "slow.lacp.actorState.synchronization",
2429         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_SYNC,
2430         "In Sync = 1, Out of Sync = 0", HFILL }},
2431
2432     { &hf_lacpdu_flags_a_collecting,
2433       { "Collecting",        "slow.lacp.actorState.collecting",
2434         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_COLLECTING,
2435         "Collection of incoming frames is: Enabled = 1, Disabled = 0", HFILL }},
2436
2437     { &hf_lacpdu_flags_a_distrib,
2438       { "Distributing",        "slow.lacp.actorState.distributing",
2439         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_DISTRIB,
2440         "Distribution of outgoing frames is: Enabled = 1, Disabled = 0", HFILL }},
2441
2442     { &hf_lacpdu_flags_a_defaulted,
2443       { "Defaulted",        "slow.lacp.actorState.defaulted",
2444         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_DEFAULTED,
2445         "1 = Actor Rx machine is using DEFAULT Partner info, 0 = using info in Rx'd LACPDU", HFILL }},
2446
2447     { &hf_lacpdu_flags_a_expired,
2448       { "Expired",        "slow.lacp.actorState.expired",
2449         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_EXPIRED,
2450         "1 = Actor Rx machine is EXPIRED, 0 = is NOT EXPIRED", HFILL }},
2451
2452     { &hf_lacpdu_actor_reserved,
2453       { "Reserved",        "slow.lacp.reserved",
2454         FT_BYTES,    BASE_NONE,    NULL,    0x0,
2455         "", HFILL }},
2456
2457     { &hf_lacpdu_partner_type,
2458       { "Partner Information",    "slow.lacp.partnerInfo",
2459         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2460         "TLV type = Partner", HFILL }},
2461
2462     { &hf_lacpdu_partner_info_len,
2463       { "Partner Information Length",            "slow.lacp.partnerInfoLen",
2464         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2465         "The length of the Partner TLV", HFILL }},
2466
2467     { &hf_lacpdu_partner_sys_priority,
2468       { "Partner System Priority",  "slow.lacp.partnerSysPriority",
2469         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2470         "The priority assigned to the Partner System by management or admin", HFILL }},
2471
2472     { &hf_lacpdu_partner_sys,
2473       { "Partner System",            "slow.lacp.partnerSystem",
2474         FT_ETHER,    BASE_NONE,    NULL,    0x0,
2475         "The Partner's System ID encoded as a MAC address", HFILL }},
2476
2477     { &hf_lacpdu_partner_key,
2478       { "Partner Key",            "slow.lacp.partnerKey",
2479         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2480         "The operational Key value assigned to the port associated with this link by the Partner", HFILL }},
2481
2482     { &hf_lacpdu_partner_port_priority,
2483       { "Partner Port Priority",            "slow.lacp.partnerPortPriority",
2484         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2485         "The priority assigned to the port by the Partner (via Management or Admin)", HFILL }},
2486
2487     { &hf_lacpdu_partner_port,
2488       { "Partner Port",            "slow.lacp.partnerPort",
2489         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2490         "The port number associated with this link assigned to the port by the Partner (via Management or Admin)", HFILL }},
2491
2492     { &hf_lacpdu_partner_state,
2493       { "Partner State",            "slow.lacp.partnerState",
2494         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2495         "The Partner's state variables for the port, encoded as bits within a single octet", HFILL }},
2496
2497     { &hf_lacpdu_flags_p_activity,
2498       { "LACP Activity",        "slow.lacp.partnerState.activity",
2499         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_ACTIVITY,
2500         "Activity control value for this link. Active = 1, Passive = 0", HFILL }},
2501
2502     { &hf_lacpdu_flags_p_timeout,
2503       { "LACP Timeout",        "slow.lacp.partnerState.timeout",
2504         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_TIMEOUT,
2505         "Timeout control value for this link. Short Timeout = 1, Long Timeout = 0", HFILL }},
2506
2507     { &hf_lacpdu_flags_p_aggregation,
2508       { "Aggregation",        "slow.lacp.partnerState.aggregation",
2509         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_AGGREGATION,
2510         "Aggregatable = 1, Individual = 0", HFILL }},
2511
2512     { &hf_lacpdu_flags_p_sync,
2513       { "Synchronization",        "slow.lacp.partnerState.synchronization",
2514         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_SYNC,
2515         "In Sync = 1, Out of Sync = 0", HFILL }},
2516
2517     { &hf_lacpdu_flags_p_collecting,
2518       { "Collecting",        "slow.lacp.partnerState.collecting",
2519         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_COLLECTING,
2520         "Collection of incoming frames is: Enabled = 1, Disabled = 0", HFILL }},
2521
2522     { &hf_lacpdu_flags_p_distrib,
2523       { "Distributing",        "slow.lacp.partnerState.distributing",
2524         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_DISTRIB,
2525         "Distribution of outgoing frames is: Enabled = 1, Disabled = 0", HFILL }},
2526
2527     { &hf_lacpdu_flags_p_defaulted,
2528       { "Defaulted",        "slow.lacp.partnerState.defaulted",
2529         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_DEFAULTED,
2530         "1 = Actor Rx machine is using DEFAULT Partner info, 0 = using info in Rx'd LACPDU", HFILL }},
2531
2532     { &hf_lacpdu_flags_p_expired,
2533       { "Expired",        "slow.lacp.partnerState.expired",
2534         FT_BOOLEAN,    8,        TFS(&tfs_yes_no),    LACPDU_FLAGS_EXPIRED,
2535         "1 = Actor Rx machine is EXPIRED, 0 = is NOT EXPIRED", HFILL }},
2536
2537     { &hf_lacpdu_partner_reserved,
2538       { "Reserved",        "slow.lacp.reserved",
2539         FT_BYTES,    BASE_NONE,    NULL,    0x0,
2540         "", HFILL }},
2541
2542     { &hf_lacpdu_coll_type,
2543       { "Collector Information",    "slow.lacp.collectorInfo",
2544         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2545         "TLV type = Collector", HFILL }},
2546
2547     { &hf_lacpdu_coll_info_len,
2548       { "Collector Information Length",            "slow.lacp.collectorInfoLen",
2549         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2550         "The length of the Collector TLV", HFILL }},
2551
2552     { &hf_lacpdu_coll_max_delay,
2553       { "Collector Max Delay",  "slow.lacp.collectorMaxDelay",
2554         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2555         "The max delay of the station tx'ing the LACPDU (in tens of usecs)", HFILL }},
2556
2557     { &hf_lacpdu_coll_reserved,
2558       { "Reserved",        "slow.lacp.coll_reserved",
2559         FT_BYTES,    BASE_NONE,    NULL,    0x0,
2560         "", HFILL }},
2561
2562     { &hf_lacpdu_term_type,
2563       { "Terminator Information",    "slow.lacp.termInfo",
2564         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2565         "TLV type = Terminator", HFILL }},
2566
2567     { &hf_lacpdu_term_len,
2568       { "Terminator Length",            "slow.lacp.termLen",
2569         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2570         "The length of the Terminator TLV", HFILL }},
2571
2572     { &hf_lacpdu_term_reserved,
2573       { "Reserved",        "slow.lacp.term_reserved",
2574         FT_BYTES,    BASE_NONE,    NULL,    0x0,
2575         "", HFILL }},
2576
2577
2578 /*
2579  *  MARKER portion
2580  */
2581
2582     { &hf_marker_version_number,
2583       { "Version Number",    "slow.marker.version",
2584         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2585         "Identifies the Marker version", HFILL }},
2586
2587     { &hf_marker_tlv_type,
2588       { "TLV Type",    "slow.marker.tlvType",
2589         FT_UINT8,    BASE_HEX,    VALS(marker_vals),    0x0,
2590         "Marker TLV type", HFILL }},
2591
2592     { &hf_marker_tlv_length,
2593       { "TLV Length",            "slow.marker.tlvLen",
2594         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2595         "The length of the Actor TLV", HFILL }},
2596
2597     { &hf_marker_req_port,
2598       { "Requester Port",  "slow.marker.requesterPort",
2599         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2600         "The Requester Port", HFILL }},
2601
2602     { &hf_marker_req_system,
2603       { "Requester System",  "slow.marker.requesterSystem",
2604         FT_ETHER,    BASE_NONE,    NULL,    0x0,
2605         "The Requester System ID encoded as a MAC address", HFILL }},
2606
2607     { &hf_marker_req_trans_id,
2608       { "Requester Transaction ID",  "slow.marker.requesterTransId",
2609         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2610         "The Requester Transaction ID", HFILL }},
2611
2612 /*
2613  *  OAMPDU portion
2614  */
2615     { &hf_oampdu_flags,
2616       { "Flags",    "slow.oam.flags",
2617         FT_UINT16,    BASE_HEX,    NULL,    0x0,
2618         "The Flags Field", HFILL }},
2619
2620     { &hf_oampdu_flags_link_fault,
2621       { "Link Fault",        "slow.oam.flags.linkFault",
2622         FT_BOOLEAN,    8,        TFS(&tfs_true_false),    OAMPDU_FLAGS_LINK_FAULT,
2623         "The PHY detected a fault in the receive direction. True = 1, False = 0", HFILL }},
2624
2625     { &hf_oampdu_flags_dying_gasp,
2626       { "Dying Gasp",        "slow.oam.flags.dyingGasp",
2627         FT_BOOLEAN,    8,        TFS(&tfs_true_false),    OAMPDU_FLAGS_DYING_GASP,
2628         "An unrecoverable local failure occured. True = 1, False = 0", HFILL }},
2629
2630     { &hf_oampdu_flags_critical_event,
2631       { "Critical Event",        "slow.oam.flags.criticalEvent",
2632         FT_BOOLEAN,    8,        TFS(&tfs_true_false),    OAMPDU_FLAGS_CRITICAL_EVENT,
2633         "A critical event has occurred. True = 1, False = 0", HFILL }},
2634
2635     { &hf_oampdu_flags_local_evaluating,
2636       { "Local Evaluating",        "slow.oam.flags.localEvaluating",
2637         FT_BOOLEAN,    8,        TFS(&tfs_true_false),    OAMPDU_FLAGS_LOCAL_EVAL,
2638         "Local DTE Discovery process in progress. True = 1, False = 0", HFILL }},
2639
2640     { &hf_oampdu_flags_local_stable,
2641       { "Local Stable",        "slow.oam.flags.localStable",
2642         FT_BOOLEAN,    8,        TFS(&tfs_true_false),    OAMPDU_FLAGS_LOCAL_STABLE,
2643         "Local DTE is Stable. True = 1, False = 0", HFILL }},
2644
2645     { &hf_oampdu_flags_remote_evaluating,
2646       { "Remote Evaluating",        "slow.oam.flags.remoteEvaluating",
2647         FT_BOOLEAN,    8,        TFS(&tfs_true_false),    OAMPDU_FLAGS_REMOTE_EVAL,
2648         "Remote DTE Discovery process in progress. True = 1, False = 0", HFILL }},
2649
2650     { &hf_oampdu_flags_remote_stable,
2651       { "Remote Stable",        "slow.oam.flags.remoteStable",
2652         FT_BOOLEAN,    8,        TFS(&tfs_true_false),    OAMPDU_FLAGS_REMOTE_STABLE,
2653         "Remote DTE is Stable. True = 1, False = 0", HFILL }},
2654
2655     { &hf_oampdu_code,
2656       { "OAMPDU code",    "slow.oam.code",
2657         FT_UINT8,    BASE_HEX,    VALS(code_vals),    0x0,
2658         "Identifies the TLVs code", HFILL }},
2659
2660     { &hf_oampdu_info_type,
2661       { "Type",    "slow.oam.info.type",
2662         FT_UINT8,    BASE_HEX,    VALS(info_type_vals),    0x0,
2663         "Identifies the TLV type", HFILL }},
2664
2665     { &hf_oampdu_info_len,
2666       { "TLV Length",    "slow.oam.info.length",
2667         FT_UINT8,    BASE_DEC,    NULL,    0x0,
2668         "Identifies the TLVs type", HFILL }},
2669
2670     { &hf_oampdu_info_version,
2671       { "TLV Version",    "slow.oam.info.version",
2672         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2673         "Identifies the TLVs version", HFILL }},
2674
2675     { &hf_oampdu_info_revision,
2676       { "TLV Revision",    "slow.oam.info.revision",
2677         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2678         "Identifies the TLVs revision", HFILL }},
2679
2680     { &hf_oampdu_info_state,
2681       { "OAM DTE States",    "slow.oam.info.state",
2682         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2683         "OAM DTE State of the Mux and the Parser", HFILL }},
2684
2685     { &hf_oampdu_info_state_parser,
2686       { "Parser Action",        "slow.oam.info.state.parser",
2687         FT_UINT8,    BASE_HEX,    VALS(&parser_vals),    0x03,
2688         "Parser Action", HFILL }},
2689
2690     { &hf_oampdu_info_state_mux,
2691       { "Muxiplexer Action",        "slow.oam.info.state.muxiplexer",
2692         FT_BOOLEAN,    8,        TFS(&mux),    0x04,
2693         "Muxiplexer Action", HFILL }},
2694
2695     { &hf_oampdu_info_oamConfig,
2696       { "OAM Configuration",    "slow.oam.info.oamConfig",
2697         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2698         "OAM Configuration", HFILL }},
2699
2700     { &hf_oampdu_info_oamConfig_mode,
2701       { "OAM Mode",        "slow.oam.info.oamConfig.mode",
2702         FT_BOOLEAN,    8,        TFS(&oam_mode),    OAMPDU_INFO_CONFIG_MODE,
2703         "", HFILL }},
2704
2705     { &hf_oampdu_info_oamConfig_uni,
2706       { "Unidirectional support",        "slow.oam.flags.dyingGasp",
2707         FT_BOOLEAN,    8,        TFS(&oam_uni),    OAMPDU_INFO_CONFIG_UNI,
2708         "Unidirectional support", HFILL }},
2709
2710     { &hf_oampdu_info_oamConfig_lpbk,
2711       { "Loopback support",        "slow.oam.flags.criticalEvent",
2712         FT_BOOLEAN,    8,        TFS(&oam_lpbk),    OAMPDU_INFO_CONFIG_LPBK,
2713         "Loopback support", HFILL }},
2714
2715     { &hf_oampdu_info_oamConfig_event,
2716       { "Link Events support",        "slow.oam.flags.localEvaluating",
2717         FT_BOOLEAN,    8,        TFS(&oam_event),    OAMPDU_INFO_CONFIG_EVENT,
2718         "Link Events support", HFILL }},
2719
2720     { &hf_oampdu_info_oamConfig_var,
2721       { "Variable Retrieval",        "slow.oam.flags.localStable",
2722         FT_BOOLEAN,    8,        TFS(&oam_var),    OAMPDU_INFO_CONFIG_VAR,
2723         "Variable Retrieval support", HFILL }},
2724
2725     { &hf_oampdu_info_oampduConfig,
2726       { "Max OAMPDU Size",    "slow.oam.info.oampduConfig",
2727         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2728         "OAMPDU Configuration", HFILL }},
2729
2730     { &hf_oampdu_info_oui,
2731       { "Organizationally Unique Identifier", "slow.oam.info.oui",
2732         FT_BYTES,    BASE_NONE,    NULL,    0x0,
2733         "", HFILL }},
2734
2735     { &hf_oampdu_info_vendor,
2736       { "Vendor Specific Information", "slow.oam.info.vendor",
2737         FT_BYTES,    BASE_NONE,    NULL,    0x0,
2738         "", HFILL }},
2739
2740     /*
2741      * Event notification definitions
2742      */
2743     { &hf_oampdu_event_sequence,
2744       { "Sequence Number",    "slow.oam.event.sequence",
2745         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2746         "Identifies the Event Notification TLVs", HFILL }},
2747
2748     { &hf_oampdu_event_type,
2749       { "Event Type",    "slow.oam.event.type",
2750         FT_UINT8,    BASE_HEX,    VALS(event_type_vals),    0x0,
2751         "Identifies the TLV type", HFILL }},
2752
2753     { &hf_oampdu_event_length,
2754       { "Event Length",    "slow.oam.event.length",
2755         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2756         "This field indicates the length in octets of the TLV-tuple", HFILL }},
2757
2758     { &hf_oampdu_event_timeStamp,
2759       { "Event Timestamp (100ms)",    "slow.oam.event.timestamp",
2760         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2761         "Event Time Stamp in term of 100 ms intervals", HFILL }},
2762
2763     /* Errored Symbol Period Event TLV */
2764     { &hf_oampdu_event_espeWindow,
2765       { "Errored Symbol Window",    "slow.oam.event.espeWindow",
2766         FT_UINT64,    BASE_DEC,    NULL,    0x0,
2767         "Number of symbols in the period", HFILL }},
2768
2769     { &hf_oampdu_event_espeThreshold,
2770       { "Errored Symbol Threshold",    "slow.oam.event.espeThreshold",
2771         FT_UINT64,    BASE_DEC,    NULL,    0x0,
2772         "Number of symbols required to generate the Event", HFILL }},
2773
2774     { &hf_oampdu_event_espeErrors,
2775       { "Errored Symbols",    "slow.oam.event.espeErrors",
2776         FT_UINT64,    BASE_DEC,    NULL,    0x0,
2777         "Number of symbols in error", HFILL }},
2778
2779     { &hf_oampdu_event_espeTotalErrors,
2780       { "Error Running Total",    "slow.oam.event.espeTotalErrors",
2781         FT_UINT64,    BASE_DEC,    NULL,    0x0,
2782         "Number of symbols in error since reset of the sublayer", HFILL }},
2783
2784     { &hf_oampdu_event_espeTotalEvents,
2785       { "Event Running Total",    "slow.oam.event.espeTotalEvents",
2786         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2787         "Total Event generated since reset of the sublayer", HFILL }},
2788
2789     /* Errored Frame Event TLV */
2790     { &hf_oampdu_event_efeWindow,
2791       { "Errored Frame Window",    "slow.oam.event.efeWindow",
2792         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2793         "Number of symbols in the period", HFILL }},
2794
2795     { &hf_oampdu_event_efeThreshold,
2796       { "Errored Frame Threshold",    "slow.oam.event.efeThreshold",
2797         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2798         "Number of frames required to generate the Event", HFILL }},
2799
2800     { &hf_oampdu_event_efeErrors,
2801       { "Errored Frames",    "slow.oam.event.efeErrors",
2802         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2803         "Number of symbols in error", HFILL }},
2804
2805     { &hf_oampdu_event_efeTotalErrors,
2806       { "Error Running Total",    "slow.oam.event.efeTotalErrors",
2807         FT_UINT64,    BASE_DEC,    NULL,    0x0,
2808         "Number of frames in error since reset of the sublayer", HFILL }},
2809
2810     { &hf_oampdu_event_efeTotalEvents,
2811       { "Event Running Total",    "slow.oam.event.efeTotalEvents",
2812         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2813         "Total Event generated since reset of the sublayer", HFILL }},
2814
2815     /* Errored Frame Period Event TLV */
2816     { &hf_oampdu_event_efpeWindow,
2817       { "Errored Frame Window",    "slow.oam.event.efpeWindow",
2818         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2819         "Number of frame in error during the period", HFILL }},
2820
2821     { &hf_oampdu_event_efpeThreshold,
2822       { "Errored Frame Threshold",    "slow.oam.event.efpeThreshold",
2823         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2824         "Number of frames required to generate the Event", HFILL }},
2825
2826     { &hf_oampdu_event_efpeErrors,
2827       { "Errored Frames",    "slow.oam.event.efeErrors",
2828         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2829         "Number of symbols in error", HFILL }},
2830
2831     { &hf_oampdu_event_efpeTotalErrors,
2832       { "Error Running Total",    "slow.oam.event.efpeTotalErrors",
2833         FT_UINT64,    BASE_DEC,    NULL,    0x0,
2834         "Number of frames in error since reset of the sublayer", HFILL }},
2835
2836     { &hf_oampdu_event_efpeTotalEvents,
2837       { "Event Running Total",    "slow.oam.event.efpeTotalEvents",
2838         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2839         "Total Event generated since reset of the sublayer", HFILL }},
2840
2841     /* Errored Frame Second Summary Event TLV */
2842     { &hf_oampdu_event_efsseWindow,
2843       { "Errored Frame Window",    "slow.oam.event.efsseWindow",
2844         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2845         "Number of frame in error during the period", HFILL }},
2846
2847     { &hf_oampdu_event_efsseThreshold,
2848       { "Errored Frame Threshold",    "slow.oam.event.efsseThreshold",
2849         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2850         "Number of frames required to generate the Event", HFILL }},
2851
2852     { &hf_oampdu_event_efsseErrors,
2853       { "Errored Frames",    "slow.oam.event.efeErrors",
2854         FT_UINT16,    BASE_DEC,    NULL,    0x0,
2855         "Number of symbols in error", HFILL }},
2856
2857     { &hf_oampdu_event_efsseTotalErrors,
2858       { "Error Running Total",    "slow.oam.event.efsseTotalErrors",
2859         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2860         "Number of frames in error since reset of the sublayer", HFILL }},
2861
2862     { &hf_oampdu_event_efsseTotalEvents,
2863       { "Event Running Total",    "slow.oam.event.efsseTotalEvents",
2864         FT_UINT32,    BASE_DEC,    NULL,    0x0,
2865         "Total Event generated since reset of the sublayer", HFILL }},
2866
2867     /* Variable request and response definitions*/
2868     { &hf_oampdu_variable_branch,
2869       { "Branch",    "slow.oam.variable.branch",
2870         FT_UINT8,    BASE_HEX,    VALS(branch_vals),    0x0,
2871         "Variable Branch, derived from the CMIP protocol in Annex 30A", HFILL }},
2872
2873     { &hf_oampdu_variable_object,
2874       { "Leaf",    "slow.oam.variable.object",
2875         FT_UINT16,    BASE_HEX,    VALS(object_vals),    0x0,
2876         "Object, derived from the CMIP protocol in Annex 30A", HFILL }},
2877
2878     { &hf_oampdu_variable_package,
2879       { "Leaf",    "slow.oam.variable.package",
2880         FT_UINT16,    BASE_HEX,    VALS(package_vals),    0x0,
2881         "Package, derived from the CMIP protocol in Annex 30A", HFILL }},
2882
2883     { &hf_oampdu_variable_binding,
2884       { "Leaf",    "slow.oam.variable.binding",
2885         FT_UINT16,    BASE_HEX,    VALS(binding_vals),    0x0,
2886         "Binding, derived from the CMIP protocol in Annex 30A", HFILL }},
2887
2888     { &hf_oampdu_variable_attribute,
2889       { "Leaf",    "slow.oam.variable.attribute",
2890         FT_UINT16,    BASE_HEX,    VALS(attribute_vals),    0x0,
2891         "Attribute, derived from the CMIP protocol in Annex 30A", HFILL }},
2892
2893     { &hf_oampdu_variable_width,
2894       { "Variable Width",    "slow.oam.variable.width",
2895         FT_UINT8,    BASE_DEC,    NULL,    0x0,
2896         "Width", HFILL }},
2897
2898     { &hf_oampdu_variable_indication,
2899       { "Variable indication",    "slow.oam.variable.indication",
2900         FT_UINT8,    BASE_HEX,    VALS(indication_vals),    0x0,
2901         "Variable indication", HFILL }},
2902
2903     { &hf_oampdu_variable_value,
2904       { "Variable Value",    "slow.oam.variable.value",
2905         FT_BYTES,    BASE_HEX,    NULL,    0x0,
2906         "Value", HFILL }},
2907
2908     /* Loopback Control definitions*/
2909     { &hf_oampdu_lpbk,
2910       { "Commands", "slow.oam.lpbk.commands",
2911         FT_UINT8,    BASE_HEX,    NULL,    0x0,
2912         "The List of Loopback Commands", HFILL }},
2913
2914     { &hf_oampdu_lpbk_enable,
2915       { "Enable Remote Loopback", "slow.oam.lpbk.commands.enable",
2916         FT_BOOLEAN,    8,        NULL,    OAMPDU_LPBK_ENABLE,
2917         "Enable Remote Loopback Command", HFILL }},
2918
2919     { &hf_oampdu_lpbk_disable,
2920       { "Disable Remote Loopback", "slow.oam.lpbk.commands.disable",
2921         FT_BOOLEAN,    8,        NULL,    OAMPDU_LPBK_DISABLE,
2922         "Disable Remote Loopback Command", HFILL }},
2923   };
2924
2925   /* Setup protocol subtree array */
2926
2927   static gint *ett[] = {
2928     &ett_pdu,
2929     &ett_lacpdu,
2930     &ett_lacpdu_a_flags,
2931     &ett_lacpdu_p_flags,
2932     &ett_marker,
2933     &ett_oampdu,
2934     &ett_oampdu_flags,
2935     &ett_oampdu_local_info,
2936     &ett_oampdu_local_info_state,
2937     &ett_oampdu_local_info_config,
2938     &ett_oampdu_remote_info,
2939     &ett_oampdu_remote_info_state,
2940     &ett_oampdu_remote_info_config,
2941     &ett_oampdu_org_info,
2942     &ett_oampdu_event_espe,
2943     &ett_oampdu_event_efe,
2944     &ett_oampdu_event_efpe,
2945     &ett_oampdu_event_efsse,
2946     &ett_oampdu_event_ose,
2947     &ett_oampdu_lpbk_ctrl,
2948
2949   };
2950
2951   /* Register the protocol name and description */
2952
2953   proto_slow = proto_register_protocol("Slow Protocols", "802.3 Slow protocols", "slow");
2954
2955   /* Required function calls to register the header fields and subtrees used */
2956
2957   proto_register_field_array(proto_slow, hf, array_length(hf));
2958   proto_register_subtree_array(ett, array_length(ett));
2959 }
2960
2961
2962 void
2963 proto_reg_handoff_slow_protocols(void)
2964 {
2965   dissector_handle_t slow_protocols_handle;
2966
2967   slow_protocols_handle = create_dissector_handle(dissect_slow_protocols, proto_slow);
2968   dissector_add("ethertype", ETHERTYPE_SLOW_PROTOCOLS, slow_protocols_handle);
2969 }