1// Copyright 2014 Google, Inc. All rights reserved. 2// 3// Use of this source code is governed by a BSD-style license 4// that can be found in the LICENSE file in the root of the source 5// tree. 6 7// See http://standards.ieee.org/findstds/standard/802.11-2012.html for info on 8// all of the layers in this file. 9 10package layers 11 12import ( 13 "bytes" 14 "encoding/binary" 15 "fmt" 16 "hash/crc32" 17 "net" 18 19 "github.com/ooni/psiphon/oopsi/github.com/google/gopacket" 20) 21 22// Dot11Flags contains the set of 8 flags in the IEEE 802.11 frame control 23// header, all in one place. 24type Dot11Flags uint8 25 26const ( 27 Dot11FlagsToDS Dot11Flags = 1 << iota 28 Dot11FlagsFromDS 29 Dot11FlagsMF 30 Dot11FlagsRetry 31 Dot11FlagsPowerManagement 32 Dot11FlagsMD 33 Dot11FlagsWEP 34 Dot11FlagsOrder 35) 36 37func (d Dot11Flags) ToDS() bool { 38 return d&Dot11FlagsToDS != 0 39} 40func (d Dot11Flags) FromDS() bool { 41 return d&Dot11FlagsFromDS != 0 42} 43func (d Dot11Flags) MF() bool { 44 return d&Dot11FlagsMF != 0 45} 46func (d Dot11Flags) Retry() bool { 47 return d&Dot11FlagsRetry != 0 48} 49func (d Dot11Flags) PowerManagement() bool { 50 return d&Dot11FlagsPowerManagement != 0 51} 52func (d Dot11Flags) MD() bool { 53 return d&Dot11FlagsMD != 0 54} 55func (d Dot11Flags) WEP() bool { 56 return d&Dot11FlagsWEP != 0 57} 58func (d Dot11Flags) Order() bool { 59 return d&Dot11FlagsOrder != 0 60} 61 62// String provides a human readable string for Dot11Flags. 63// This string is possibly subject to change over time; if you're storing this 64// persistently, you should probably store the Dot11Flags value, not its string. 65func (a Dot11Flags) String() string { 66 var out bytes.Buffer 67 if a.ToDS() { 68 out.WriteString("TO-DS,") 69 } 70 if a.FromDS() { 71 out.WriteString("FROM-DS,") 72 } 73 if a.MF() { 74 out.WriteString("MF,") 75 } 76 if a.Retry() { 77 out.WriteString("Retry,") 78 } 79 if a.PowerManagement() { 80 out.WriteString("PowerManagement,") 81 } 82 if a.MD() { 83 out.WriteString("MD,") 84 } 85 if a.WEP() { 86 out.WriteString("WEP,") 87 } 88 if a.Order() { 89 out.WriteString("Order,") 90 } 91 92 if length := out.Len(); length > 0 { 93 return string(out.Bytes()[:length-1]) // strip final comma 94 } 95 return "" 96} 97 98type Dot11Reason uint16 99 100// TODO: Verify these reasons, and append more reasons if necessary. 101 102const ( 103 Dot11ReasonReserved Dot11Reason = 1 104 Dot11ReasonUnspecified Dot11Reason = 2 105 Dot11ReasonAuthExpired Dot11Reason = 3 106 Dot11ReasonDeauthStLeaving Dot11Reason = 4 107 Dot11ReasonInactivity Dot11Reason = 5 108 Dot11ReasonApFull Dot11Reason = 6 109 Dot11ReasonClass2FromNonAuth Dot11Reason = 7 110 Dot11ReasonClass3FromNonAss Dot11Reason = 8 111 Dot11ReasonDisasStLeaving Dot11Reason = 9 112 Dot11ReasonStNotAuth Dot11Reason = 10 113) 114 115// String provides a human readable string for Dot11Reason. 116// This string is possibly subject to change over time; if you're storing this 117// persistently, you should probably store the Dot11Reason value, not its string. 118func (a Dot11Reason) String() string { 119 switch a { 120 case Dot11ReasonReserved: 121 return "Reserved" 122 case Dot11ReasonUnspecified: 123 return "Unspecified" 124 case Dot11ReasonAuthExpired: 125 return "Auth. expired" 126 case Dot11ReasonDeauthStLeaving: 127 return "Deauth. st. leaving" 128 case Dot11ReasonInactivity: 129 return "Inactivity" 130 case Dot11ReasonApFull: 131 return "Ap. full" 132 case Dot11ReasonClass2FromNonAuth: 133 return "Class2 from non auth." 134 case Dot11ReasonClass3FromNonAss: 135 return "Class3 from non ass." 136 case Dot11ReasonDisasStLeaving: 137 return "Disass st. leaving" 138 case Dot11ReasonStNotAuth: 139 return "St. not auth." 140 default: 141 return "Unknown reason" 142 } 143} 144 145type Dot11Status uint16 146 147const ( 148 Dot11StatusSuccess Dot11Status = 0 149 Dot11StatusFailure Dot11Status = 1 // Unspecified failure 150 Dot11StatusCannotSupportAllCapabilities Dot11Status = 10 // Cannot support all requested capabilities in the Capability Information field 151 Dot11StatusInabilityExistsAssociation Dot11Status = 11 // Reassociation denied due to inability to confirm that association exists 152 Dot11StatusAssociationDenied Dot11Status = 12 // Association denied due to reason outside the scope of this standard 153 Dot11StatusAlgorithmUnsupported Dot11Status = 13 // Responding station does not support the specified authentication algorithm 154 Dot11StatusOufOfExpectedSequence Dot11Status = 14 // Received an Authentication frame with authentication transaction sequence number out of expected sequence 155 Dot11StatusChallengeFailure Dot11Status = 15 // Authentication rejected because of challenge failure 156 Dot11StatusTimeout Dot11Status = 16 // Authentication rejected due to timeout waiting for next frame in sequence 157 Dot11StatusAPUnableToHandle Dot11Status = 17 // Association denied because AP is unable to handle additional associated stations 158 Dot11StatusRateUnsupported Dot11Status = 18 // Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter 159) 160 161// String provides a human readable string for Dot11Status. 162// This string is possibly subject to change over time; if you're storing this 163// persistently, you should probably store the Dot11Status value, not its string. 164func (a Dot11Status) String() string { 165 switch a { 166 case Dot11StatusSuccess: 167 return "success" 168 case Dot11StatusFailure: 169 return "failure" 170 case Dot11StatusCannotSupportAllCapabilities: 171 return "cannot-support-all-capabilities" 172 case Dot11StatusInabilityExistsAssociation: 173 return "inability-exists-association" 174 case Dot11StatusAssociationDenied: 175 return "association-denied" 176 case Dot11StatusAlgorithmUnsupported: 177 return "algorithm-unsupported" 178 case Dot11StatusOufOfExpectedSequence: 179 return "out-of-expected-sequence" 180 case Dot11StatusChallengeFailure: 181 return "challenge-failure" 182 case Dot11StatusTimeout: 183 return "timeout" 184 case Dot11StatusAPUnableToHandle: 185 return "ap-unable-to-handle" 186 case Dot11StatusRateUnsupported: 187 return "rate-unsupported" 188 default: 189 return "unknown status" 190 } 191} 192 193type Dot11AckPolicy uint8 194 195const ( 196 Dot11AckPolicyNormal Dot11AckPolicy = 0 197 Dot11AckPolicyNone Dot11AckPolicy = 1 198 Dot11AckPolicyNoExplicit Dot11AckPolicy = 2 199 Dot11AckPolicyBlock Dot11AckPolicy = 3 200) 201 202// String provides a human readable string for Dot11AckPolicy. 203// This string is possibly subject to change over time; if you're storing this 204// persistently, you should probably store the Dot11AckPolicy value, not its string. 205func (a Dot11AckPolicy) String() string { 206 switch a { 207 case Dot11AckPolicyNormal: 208 return "normal-ack" 209 case Dot11AckPolicyNone: 210 return "no-ack" 211 case Dot11AckPolicyNoExplicit: 212 return "no-explicit-ack" 213 case Dot11AckPolicyBlock: 214 return "block-ack" 215 default: 216 return "unknown-ack-policy" 217 } 218} 219 220type Dot11Algorithm uint16 221 222const ( 223 Dot11AlgorithmOpen Dot11Algorithm = 0 224 Dot11AlgorithmSharedKey Dot11Algorithm = 1 225) 226 227// String provides a human readable string for Dot11Algorithm. 228// This string is possibly subject to change over time; if you're storing this 229// persistently, you should probably store the Dot11Algorithm value, not its string. 230func (a Dot11Algorithm) String() string { 231 switch a { 232 case Dot11AlgorithmOpen: 233 return "open" 234 case Dot11AlgorithmSharedKey: 235 return "shared-key" 236 default: 237 return "unknown-algorithm" 238 } 239} 240 241type Dot11InformationElementID uint8 242 243const ( 244 Dot11InformationElementIDSSID Dot11InformationElementID = 0 245 Dot11InformationElementIDRates Dot11InformationElementID = 1 246 Dot11InformationElementIDFHSet Dot11InformationElementID = 2 247 Dot11InformationElementIDDSSet Dot11InformationElementID = 3 248 Dot11InformationElementIDCFSet Dot11InformationElementID = 4 249 Dot11InformationElementIDTIM Dot11InformationElementID = 5 250 Dot11InformationElementIDIBSSSet Dot11InformationElementID = 6 251 Dot11InformationElementIDCountryInfo Dot11InformationElementID = 7 252 Dot11InformationElementIDHoppingPatternParam Dot11InformationElementID = 8 253 Dot11InformationElementIDHoppingPatternTable Dot11InformationElementID = 9 254 Dot11InformationElementIDRequest Dot11InformationElementID = 10 255 Dot11InformationElementIDQBSSLoadElem Dot11InformationElementID = 11 256 Dot11InformationElementIDEDCAParamSet Dot11InformationElementID = 12 257 Dot11InformationElementIDTrafficSpec Dot11InformationElementID = 13 258 Dot11InformationElementIDTrafficClass Dot11InformationElementID = 14 259 Dot11InformationElementIDSchedule Dot11InformationElementID = 15 260 Dot11InformationElementIDChallenge Dot11InformationElementID = 16 261 Dot11InformationElementIDPowerConst Dot11InformationElementID = 32 262 Dot11InformationElementIDPowerCapability Dot11InformationElementID = 33 263 Dot11InformationElementIDTPCRequest Dot11InformationElementID = 34 264 Dot11InformationElementIDTPCReport Dot11InformationElementID = 35 265 Dot11InformationElementIDSupportedChannels Dot11InformationElementID = 36 266 Dot11InformationElementIDSwitchChannelAnnounce Dot11InformationElementID = 37 267 Dot11InformationElementIDMeasureRequest Dot11InformationElementID = 38 268 Dot11InformationElementIDMeasureReport Dot11InformationElementID = 39 269 Dot11InformationElementIDQuiet Dot11InformationElementID = 40 270 Dot11InformationElementIDIBSSDFS Dot11InformationElementID = 41 271 Dot11InformationElementIDERPInfo Dot11InformationElementID = 42 272 Dot11InformationElementIDTSDelay Dot11InformationElementID = 43 273 Dot11InformationElementIDTCLASProcessing Dot11InformationElementID = 44 274 Dot11InformationElementIDHTCapabilities Dot11InformationElementID = 45 275 Dot11InformationElementIDQOSCapability Dot11InformationElementID = 46 276 Dot11InformationElementIDERPInfo2 Dot11InformationElementID = 47 277 Dot11InformationElementIDRSNInfo Dot11InformationElementID = 48 278 Dot11InformationElementIDESRates Dot11InformationElementID = 50 279 Dot11InformationElementIDAPChannelReport Dot11InformationElementID = 51 280 Dot11InformationElementIDNeighborReport Dot11InformationElementID = 52 281 Dot11InformationElementIDRCPI Dot11InformationElementID = 53 282 Dot11InformationElementIDMobilityDomain Dot11InformationElementID = 54 283 Dot11InformationElementIDFastBSSTrans Dot11InformationElementID = 55 284 Dot11InformationElementIDTimeoutInt Dot11InformationElementID = 56 285 Dot11InformationElementIDRICData Dot11InformationElementID = 57 286 Dot11InformationElementIDDSERegisteredLoc Dot11InformationElementID = 58 287 Dot11InformationElementIDSuppOperatingClass Dot11InformationElementID = 59 288 Dot11InformationElementIDExtChanSwitchAnnounce Dot11InformationElementID = 60 289 Dot11InformationElementIDHTInfo Dot11InformationElementID = 61 290 Dot11InformationElementIDSecChanOffset Dot11InformationElementID = 62 291 Dot11InformationElementIDBSSAverageAccessDelay Dot11InformationElementID = 63 292 Dot11InformationElementIDAntenna Dot11InformationElementID = 64 293 Dot11InformationElementIDRSNI Dot11InformationElementID = 65 294 Dot11InformationElementIDMeasurePilotTrans Dot11InformationElementID = 66 295 Dot11InformationElementIDBSSAvailAdmCapacity Dot11InformationElementID = 67 296 Dot11InformationElementIDBSSACAccDelayWAPIParam Dot11InformationElementID = 68 297 Dot11InformationElementIDTimeAdvertisement Dot11InformationElementID = 69 298 Dot11InformationElementIDRMEnabledCapabilities Dot11InformationElementID = 70 299 Dot11InformationElementIDMultipleBSSID Dot11InformationElementID = 71 300 Dot11InformationElementID2040BSSCoExist Dot11InformationElementID = 72 301 Dot11InformationElementID2040BSSIntChanReport Dot11InformationElementID = 73 302 Dot11InformationElementIDOverlapBSSScanParam Dot11InformationElementID = 74 303 Dot11InformationElementIDRICDescriptor Dot11InformationElementID = 75 304 Dot11InformationElementIDManagementMIC Dot11InformationElementID = 76 305 Dot11InformationElementIDEventRequest Dot11InformationElementID = 78 306 Dot11InformationElementIDEventReport Dot11InformationElementID = 79 307 Dot11InformationElementIDDiagnosticRequest Dot11InformationElementID = 80 308 Dot11InformationElementIDDiagnosticReport Dot11InformationElementID = 81 309 Dot11InformationElementIDLocationParam Dot11InformationElementID = 82 310 Dot11InformationElementIDNonTransBSSIDCapability Dot11InformationElementID = 83 311 Dot11InformationElementIDSSIDList Dot11InformationElementID = 84 312 Dot11InformationElementIDMultipleBSSIDIndex Dot11InformationElementID = 85 313 Dot11InformationElementIDFMSDescriptor Dot11InformationElementID = 86 314 Dot11InformationElementIDFMSRequest Dot11InformationElementID = 87 315 Dot11InformationElementIDFMSResponse Dot11InformationElementID = 88 316 Dot11InformationElementIDQOSTrafficCapability Dot11InformationElementID = 89 317 Dot11InformationElementIDBSSMaxIdlePeriod Dot11InformationElementID = 90 318 Dot11InformationElementIDTFSRequest Dot11InformationElementID = 91 319 Dot11InformationElementIDTFSResponse Dot11InformationElementID = 92 320 Dot11InformationElementIDWNMSleepMode Dot11InformationElementID = 93 321 Dot11InformationElementIDTIMBroadcastRequest Dot11InformationElementID = 94 322 Dot11InformationElementIDTIMBroadcastResponse Dot11InformationElementID = 95 323 Dot11InformationElementIDCollInterferenceReport Dot11InformationElementID = 96 324 Dot11InformationElementIDChannelUsage Dot11InformationElementID = 97 325 Dot11InformationElementIDTimeZone Dot11InformationElementID = 98 326 Dot11InformationElementIDDMSRequest Dot11InformationElementID = 99 327 Dot11InformationElementIDDMSResponse Dot11InformationElementID = 100 328 Dot11InformationElementIDLinkIdentifier Dot11InformationElementID = 101 329 Dot11InformationElementIDWakeupSchedule Dot11InformationElementID = 102 330 Dot11InformationElementIDChannelSwitchTiming Dot11InformationElementID = 104 331 Dot11InformationElementIDPTIControl Dot11InformationElementID = 105 332 Dot11InformationElementIDPUBufferStatus Dot11InformationElementID = 106 333 Dot11InformationElementIDInterworking Dot11InformationElementID = 107 334 Dot11InformationElementIDAdvertisementProtocol Dot11InformationElementID = 108 335 Dot11InformationElementIDExpBWRequest Dot11InformationElementID = 109 336 Dot11InformationElementIDQOSMapSet Dot11InformationElementID = 110 337 Dot11InformationElementIDRoamingConsortium Dot11InformationElementID = 111 338 Dot11InformationElementIDEmergencyAlertIdentifier Dot11InformationElementID = 112 339 Dot11InformationElementIDMeshConfiguration Dot11InformationElementID = 113 340 Dot11InformationElementIDMeshID Dot11InformationElementID = 114 341 Dot11InformationElementIDMeshLinkMetricReport Dot11InformationElementID = 115 342 Dot11InformationElementIDCongestionNotification Dot11InformationElementID = 116 343 Dot11InformationElementIDMeshPeeringManagement Dot11InformationElementID = 117 344 Dot11InformationElementIDMeshChannelSwitchParam Dot11InformationElementID = 118 345 Dot11InformationElementIDMeshAwakeWindows Dot11InformationElementID = 119 346 Dot11InformationElementIDBeaconTiming Dot11InformationElementID = 120 347 Dot11InformationElementIDMCCAOPSetupRequest Dot11InformationElementID = 121 348 Dot11InformationElementIDMCCAOPSetupReply Dot11InformationElementID = 122 349 Dot11InformationElementIDMCCAOPAdvertisement Dot11InformationElementID = 123 350 Dot11InformationElementIDMCCAOPTeardown Dot11InformationElementID = 124 351 Dot11InformationElementIDGateAnnouncement Dot11InformationElementID = 125 352 Dot11InformationElementIDRootAnnouncement Dot11InformationElementID = 126 353 Dot11InformationElementIDExtCapability Dot11InformationElementID = 127 354 Dot11InformationElementIDAgereProprietary Dot11InformationElementID = 128 355 Dot11InformationElementIDPathRequest Dot11InformationElementID = 130 356 Dot11InformationElementIDPathReply Dot11InformationElementID = 131 357 Dot11InformationElementIDPathError Dot11InformationElementID = 132 358 Dot11InformationElementIDCiscoCCX1CKIPDeviceName Dot11InformationElementID = 133 359 Dot11InformationElementIDCiscoCCX2 Dot11InformationElementID = 136 360 Dot11InformationElementIDProxyUpdate Dot11InformationElementID = 137 361 Dot11InformationElementIDProxyUpdateConfirmation Dot11InformationElementID = 138 362 Dot11InformationElementIDAuthMeshPerringExch Dot11InformationElementID = 139 363 Dot11InformationElementIDMIC Dot11InformationElementID = 140 364 Dot11InformationElementIDDestinationURI Dot11InformationElementID = 141 365 Dot11InformationElementIDUAPSDCoexistence Dot11InformationElementID = 142 366 Dot11InformationElementIDWakeupSchedule80211ad Dot11InformationElementID = 143 367 Dot11InformationElementIDExtendedSchedule Dot11InformationElementID = 144 368 Dot11InformationElementIDSTAAvailability Dot11InformationElementID = 145 369 Dot11InformationElementIDDMGTSPEC Dot11InformationElementID = 146 370 Dot11InformationElementIDNextDMGATI Dot11InformationElementID = 147 371 Dot11InformationElementIDDMSCapabilities Dot11InformationElementID = 148 372 Dot11InformationElementIDCiscoUnknown95 Dot11InformationElementID = 149 373 Dot11InformationElementIDVendor2 Dot11InformationElementID = 150 374 Dot11InformationElementIDDMGOperating Dot11InformationElementID = 151 375 Dot11InformationElementIDDMGBSSParamChange Dot11InformationElementID = 152 376 Dot11InformationElementIDDMGBeamRefinement Dot11InformationElementID = 153 377 Dot11InformationElementIDChannelMeasFeedback Dot11InformationElementID = 154 378 Dot11InformationElementIDAwakeWindow Dot11InformationElementID = 157 379 Dot11InformationElementIDMultiBand Dot11InformationElementID = 158 380 Dot11InformationElementIDADDBAExtension Dot11InformationElementID = 159 381 Dot11InformationElementIDNEXTPCPList Dot11InformationElementID = 160 382 Dot11InformationElementIDPCPHandover Dot11InformationElementID = 161 383 Dot11InformationElementIDDMGLinkMargin Dot11InformationElementID = 162 384 Dot11InformationElementIDSwitchingStream Dot11InformationElementID = 163 385 Dot11InformationElementIDSessionTransmission Dot11InformationElementID = 164 386 Dot11InformationElementIDDynamicTonePairReport Dot11InformationElementID = 165 387 Dot11InformationElementIDClusterReport Dot11InformationElementID = 166 388 Dot11InformationElementIDRelayCapabilities Dot11InformationElementID = 167 389 Dot11InformationElementIDRelayTransferParameter Dot11InformationElementID = 168 390 Dot11InformationElementIDBeamlinkMaintenance Dot11InformationElementID = 169 391 Dot11InformationElementIDMultipleMacSublayers Dot11InformationElementID = 170 392 Dot11InformationElementIDUPID Dot11InformationElementID = 171 393 Dot11InformationElementIDDMGLinkAdaptionAck Dot11InformationElementID = 172 394 Dot11InformationElementIDSymbolProprietary Dot11InformationElementID = 173 395 Dot11InformationElementIDMCCAOPAdvertOverview Dot11InformationElementID = 174 396 Dot11InformationElementIDQuietPeriodRequest Dot11InformationElementID = 175 397 Dot11InformationElementIDQuietPeriodResponse Dot11InformationElementID = 177 398 Dot11InformationElementIDECPACPolicy Dot11InformationElementID = 182 399 Dot11InformationElementIDClusterTimeOffset Dot11InformationElementID = 183 400 Dot11InformationElementIDAntennaSectorID Dot11InformationElementID = 190 401 Dot11InformationElementIDVHTCapabilities Dot11InformationElementID = 191 402 Dot11InformationElementIDVHTOperation Dot11InformationElementID = 192 403 Dot11InformationElementIDExtendedBSSLoad Dot11InformationElementID = 193 404 Dot11InformationElementIDWideBWChannelSwitch Dot11InformationElementID = 194 405 Dot11InformationElementIDVHTTxPowerEnvelope Dot11InformationElementID = 195 406 Dot11InformationElementIDChannelSwitchWrapper Dot11InformationElementID = 196 407 Dot11InformationElementIDOperatingModeNotification Dot11InformationElementID = 199 408 Dot11InformationElementIDUPSIM Dot11InformationElementID = 200 409 Dot11InformationElementIDReducedNeighborReport Dot11InformationElementID = 201 410 Dot11InformationElementIDTVHTOperation Dot11InformationElementID = 202 411 Dot11InformationElementIDDeviceLocation Dot11InformationElementID = 204 412 Dot11InformationElementIDWhiteSpaceMap Dot11InformationElementID = 205 413 Dot11InformationElementIDFineTuningMeasureParams Dot11InformationElementID = 206 414 Dot11InformationElementIDVendor Dot11InformationElementID = 221 415) 416 417// String provides a human readable string for Dot11InformationElementID. 418// This string is possibly subject to change over time; if you're storing this 419// persistently, you should probably store the Dot11InformationElementID value, 420// not its string. 421func (a Dot11InformationElementID) String() string { 422 switch a { 423 case Dot11InformationElementIDSSID: 424 return "SSID parameter set" 425 case Dot11InformationElementIDRates: 426 return "Supported Rates" 427 case Dot11InformationElementIDFHSet: 428 return "FH Parameter set" 429 case Dot11InformationElementIDDSSet: 430 return "DS Parameter set" 431 case Dot11InformationElementIDCFSet: 432 return "CF Parameter set" 433 case Dot11InformationElementIDTIM: 434 return "Traffic Indication Map (TIM)" 435 case Dot11InformationElementIDIBSSSet: 436 return "IBSS Parameter set" 437 case Dot11InformationElementIDCountryInfo: 438 return "Country Information" 439 case Dot11InformationElementIDHoppingPatternParam: 440 return "Hopping Pattern Parameters" 441 case Dot11InformationElementIDHoppingPatternTable: 442 return "Hopping Pattern Table" 443 case Dot11InformationElementIDRequest: 444 return "Request" 445 case Dot11InformationElementIDQBSSLoadElem: 446 return "QBSS Load Element" 447 case Dot11InformationElementIDEDCAParamSet: 448 return "EDCA Parameter Set" 449 case Dot11InformationElementIDTrafficSpec: 450 return "Traffic Specification" 451 case Dot11InformationElementIDTrafficClass: 452 return "Traffic Classification" 453 case Dot11InformationElementIDSchedule: 454 return "Schedule" 455 case Dot11InformationElementIDChallenge: 456 return "Challenge text" 457 case Dot11InformationElementIDPowerConst: 458 return "Power Constraint" 459 case Dot11InformationElementIDPowerCapability: 460 return "Power Capability" 461 case Dot11InformationElementIDTPCRequest: 462 return "TPC Request" 463 case Dot11InformationElementIDTPCReport: 464 return "TPC Report" 465 case Dot11InformationElementIDSupportedChannels: 466 return "Supported Channels" 467 case Dot11InformationElementIDSwitchChannelAnnounce: 468 return "Channel Switch Announcement" 469 case Dot11InformationElementIDMeasureRequest: 470 return "Measurement Request" 471 case Dot11InformationElementIDMeasureReport: 472 return "Measurement Report" 473 case Dot11InformationElementIDQuiet: 474 return "Quiet" 475 case Dot11InformationElementIDIBSSDFS: 476 return "IBSS DFS" 477 case Dot11InformationElementIDERPInfo: 478 return "ERP Information" 479 case Dot11InformationElementIDTSDelay: 480 return "TS Delay" 481 case Dot11InformationElementIDTCLASProcessing: 482 return "TCLAS Processing" 483 case Dot11InformationElementIDHTCapabilities: 484 return "HT Capabilities (802.11n D1.10)" 485 case Dot11InformationElementIDQOSCapability: 486 return "QOS Capability" 487 case Dot11InformationElementIDERPInfo2: 488 return "ERP Information-2" 489 case Dot11InformationElementIDRSNInfo: 490 return "RSN Information" 491 case Dot11InformationElementIDESRates: 492 return "Extended Supported Rates" 493 case Dot11InformationElementIDAPChannelReport: 494 return "AP Channel Report" 495 case Dot11InformationElementIDNeighborReport: 496 return "Neighbor Report" 497 case Dot11InformationElementIDRCPI: 498 return "RCPI" 499 case Dot11InformationElementIDMobilityDomain: 500 return "Mobility Domain" 501 case Dot11InformationElementIDFastBSSTrans: 502 return "Fast BSS Transition" 503 case Dot11InformationElementIDTimeoutInt: 504 return "Timeout Interval" 505 case Dot11InformationElementIDRICData: 506 return "RIC Data" 507 case Dot11InformationElementIDDSERegisteredLoc: 508 return "DSE Registered Location" 509 case Dot11InformationElementIDSuppOperatingClass: 510 return "Supported Operating Classes" 511 case Dot11InformationElementIDExtChanSwitchAnnounce: 512 return "Extended Channel Switch Announcement" 513 case Dot11InformationElementIDHTInfo: 514 return "HT Information (802.11n D1.10)" 515 case Dot11InformationElementIDSecChanOffset: 516 return "Secondary Channel Offset (802.11n D1.10)" 517 case Dot11InformationElementIDBSSAverageAccessDelay: 518 return "BSS Average Access Delay" 519 case Dot11InformationElementIDAntenna: 520 return "Antenna" 521 case Dot11InformationElementIDRSNI: 522 return "RSNI" 523 case Dot11InformationElementIDMeasurePilotTrans: 524 return "Measurement Pilot Transmission" 525 case Dot11InformationElementIDBSSAvailAdmCapacity: 526 return "BSS Available Admission Capacity" 527 case Dot11InformationElementIDBSSACAccDelayWAPIParam: 528 return "BSS AC Access Delay/WAPI Parameter Set" 529 case Dot11InformationElementIDTimeAdvertisement: 530 return "Time Advertisement" 531 case Dot11InformationElementIDRMEnabledCapabilities: 532 return "RM Enabled Capabilities" 533 case Dot11InformationElementIDMultipleBSSID: 534 return "Multiple BSSID" 535 case Dot11InformationElementID2040BSSCoExist: 536 return "20/40 BSS Coexistence" 537 case Dot11InformationElementID2040BSSIntChanReport: 538 return "20/40 BSS Intolerant Channel Report" 539 case Dot11InformationElementIDOverlapBSSScanParam: 540 return "Overlapping BSS Scan Parameters" 541 case Dot11InformationElementIDRICDescriptor: 542 return "RIC Descriptor" 543 case Dot11InformationElementIDManagementMIC: 544 return "Management MIC" 545 case Dot11InformationElementIDEventRequest: 546 return "Event Request" 547 case Dot11InformationElementIDEventReport: 548 return "Event Report" 549 case Dot11InformationElementIDDiagnosticRequest: 550 return "Diagnostic Request" 551 case Dot11InformationElementIDDiagnosticReport: 552 return "Diagnostic Report" 553 case Dot11InformationElementIDLocationParam: 554 return "Location Parameters" 555 case Dot11InformationElementIDNonTransBSSIDCapability: 556 return "Non Transmitted BSSID Capability" 557 case Dot11InformationElementIDSSIDList: 558 return "SSID List" 559 case Dot11InformationElementIDMultipleBSSIDIndex: 560 return "Multiple BSSID Index" 561 case Dot11InformationElementIDFMSDescriptor: 562 return "FMS Descriptor" 563 case Dot11InformationElementIDFMSRequest: 564 return "FMS Request" 565 case Dot11InformationElementIDFMSResponse: 566 return "FMS Response" 567 case Dot11InformationElementIDQOSTrafficCapability: 568 return "QoS Traffic Capability" 569 case Dot11InformationElementIDBSSMaxIdlePeriod: 570 return "BSS Max Idle Period" 571 case Dot11InformationElementIDTFSRequest: 572 return "TFS Request" 573 case Dot11InformationElementIDTFSResponse: 574 return "TFS Response" 575 case Dot11InformationElementIDWNMSleepMode: 576 return "WNM-Sleep Mode" 577 case Dot11InformationElementIDTIMBroadcastRequest: 578 return "TIM Broadcast Request" 579 case Dot11InformationElementIDTIMBroadcastResponse: 580 return "TIM Broadcast Response" 581 case Dot11InformationElementIDCollInterferenceReport: 582 return "Collocated Interference Report" 583 case Dot11InformationElementIDChannelUsage: 584 return "Channel Usage" 585 case Dot11InformationElementIDTimeZone: 586 return "Time Zone" 587 case Dot11InformationElementIDDMSRequest: 588 return "DMS Request" 589 case Dot11InformationElementIDDMSResponse: 590 return "DMS Response" 591 case Dot11InformationElementIDLinkIdentifier: 592 return "Link Identifier" 593 case Dot11InformationElementIDWakeupSchedule: 594 return "Wakeup Schedule" 595 case Dot11InformationElementIDChannelSwitchTiming: 596 return "Channel Switch Timing" 597 case Dot11InformationElementIDPTIControl: 598 return "PTI Control" 599 case Dot11InformationElementIDPUBufferStatus: 600 return "PU Buffer Status" 601 case Dot11InformationElementIDInterworking: 602 return "Interworking" 603 case Dot11InformationElementIDAdvertisementProtocol: 604 return "Advertisement Protocol" 605 case Dot11InformationElementIDExpBWRequest: 606 return "Expedited Bandwidth Request" 607 case Dot11InformationElementIDQOSMapSet: 608 return "QoS Map Set" 609 case Dot11InformationElementIDRoamingConsortium: 610 return "Roaming Consortium" 611 case Dot11InformationElementIDEmergencyAlertIdentifier: 612 return "Emergency Alert Identifier" 613 case Dot11InformationElementIDMeshConfiguration: 614 return "Mesh Configuration" 615 case Dot11InformationElementIDMeshID: 616 return "Mesh ID" 617 case Dot11InformationElementIDMeshLinkMetricReport: 618 return "Mesh Link Metric Report" 619 case Dot11InformationElementIDCongestionNotification: 620 return "Congestion Notification" 621 case Dot11InformationElementIDMeshPeeringManagement: 622 return "Mesh Peering Management" 623 case Dot11InformationElementIDMeshChannelSwitchParam: 624 return "Mesh Channel Switch Parameters" 625 case Dot11InformationElementIDMeshAwakeWindows: 626 return "Mesh Awake Windows" 627 case Dot11InformationElementIDBeaconTiming: 628 return "Beacon Timing" 629 case Dot11InformationElementIDMCCAOPSetupRequest: 630 return "MCCAOP Setup Request" 631 case Dot11InformationElementIDMCCAOPSetupReply: 632 return "MCCAOP SETUP Reply" 633 case Dot11InformationElementIDMCCAOPAdvertisement: 634 return "MCCAOP Advertisement" 635 case Dot11InformationElementIDMCCAOPTeardown: 636 return "MCCAOP Teardown" 637 case Dot11InformationElementIDGateAnnouncement: 638 return "Gate Announcement" 639 case Dot11InformationElementIDRootAnnouncement: 640 return "Root Announcement" 641 case Dot11InformationElementIDExtCapability: 642 return "Extended Capabilities" 643 case Dot11InformationElementIDAgereProprietary: 644 return "Agere Proprietary" 645 case Dot11InformationElementIDPathRequest: 646 return "Path Request" 647 case Dot11InformationElementIDPathReply: 648 return "Path Reply" 649 case Dot11InformationElementIDPathError: 650 return "Path Error" 651 case Dot11InformationElementIDCiscoCCX1CKIPDeviceName: 652 return "Cisco CCX1 CKIP + Device Name" 653 case Dot11InformationElementIDCiscoCCX2: 654 return "Cisco CCX2" 655 case Dot11InformationElementIDProxyUpdate: 656 return "Proxy Update" 657 case Dot11InformationElementIDProxyUpdateConfirmation: 658 return "Proxy Update Confirmation" 659 case Dot11InformationElementIDAuthMeshPerringExch: 660 return "Auhenticated Mesh Perring Exchange" 661 case Dot11InformationElementIDMIC: 662 return "MIC (Message Integrity Code)" 663 case Dot11InformationElementIDDestinationURI: 664 return "Destination URI" 665 case Dot11InformationElementIDUAPSDCoexistence: 666 return "U-APSD Coexistence" 667 case Dot11InformationElementIDWakeupSchedule80211ad: 668 return "Wakeup Schedule 802.11ad" 669 case Dot11InformationElementIDExtendedSchedule: 670 return "Extended Schedule" 671 case Dot11InformationElementIDSTAAvailability: 672 return "STA Availability" 673 case Dot11InformationElementIDDMGTSPEC: 674 return "DMG TSPEC" 675 case Dot11InformationElementIDNextDMGATI: 676 return "Next DMG ATI" 677 case Dot11InformationElementIDDMSCapabilities: 678 return "DMG Capabilities" 679 case Dot11InformationElementIDCiscoUnknown95: 680 return "Cisco Unknown 95" 681 case Dot11InformationElementIDVendor2: 682 return "Vendor Specific" 683 case Dot11InformationElementIDDMGOperating: 684 return "DMG Operating" 685 case Dot11InformationElementIDDMGBSSParamChange: 686 return "DMG BSS Parameter Change" 687 case Dot11InformationElementIDDMGBeamRefinement: 688 return "DMG Beam Refinement" 689 case Dot11InformationElementIDChannelMeasFeedback: 690 return "Channel Measurement Feedback" 691 case Dot11InformationElementIDAwakeWindow: 692 return "Awake Window" 693 case Dot11InformationElementIDMultiBand: 694 return "Multi Band" 695 case Dot11InformationElementIDADDBAExtension: 696 return "ADDBA Extension" 697 case Dot11InformationElementIDNEXTPCPList: 698 return "NEXTPCP List" 699 case Dot11InformationElementIDPCPHandover: 700 return "PCP Handover" 701 case Dot11InformationElementIDDMGLinkMargin: 702 return "DMG Link Margin" 703 case Dot11InformationElementIDSwitchingStream: 704 return "Switching Stream" 705 case Dot11InformationElementIDSessionTransmission: 706 return "Session Transmission" 707 case Dot11InformationElementIDDynamicTonePairReport: 708 return "Dynamic Tone Pairing Report" 709 case Dot11InformationElementIDClusterReport: 710 return "Cluster Report" 711 case Dot11InformationElementIDRelayCapabilities: 712 return "Relay Capabilities" 713 case Dot11InformationElementIDRelayTransferParameter: 714 return "Relay Transfer Parameter" 715 case Dot11InformationElementIDBeamlinkMaintenance: 716 return "Beamlink Maintenance" 717 case Dot11InformationElementIDMultipleMacSublayers: 718 return "Multiple MAC Sublayers" 719 case Dot11InformationElementIDUPID: 720 return "U-PID" 721 case Dot11InformationElementIDDMGLinkAdaptionAck: 722 return "DMG Link Adaption Acknowledgment" 723 case Dot11InformationElementIDSymbolProprietary: 724 return "Symbol Proprietary" 725 case Dot11InformationElementIDMCCAOPAdvertOverview: 726 return "MCCAOP Advertisement Overview" 727 case Dot11InformationElementIDQuietPeriodRequest: 728 return "Quiet Period Request" 729 case Dot11InformationElementIDQuietPeriodResponse: 730 return "Quiet Period Response" 731 case Dot11InformationElementIDECPACPolicy: 732 return "ECPAC Policy" 733 case Dot11InformationElementIDClusterTimeOffset: 734 return "Cluster Time Offset" 735 case Dot11InformationElementIDAntennaSectorID: 736 return "Antenna Sector ID" 737 case Dot11InformationElementIDVHTCapabilities: 738 return "VHT Capabilities (IEEE Std 802.11ac/D3.1)" 739 case Dot11InformationElementIDVHTOperation: 740 return "VHT Operation (IEEE Std 802.11ac/D3.1)" 741 case Dot11InformationElementIDExtendedBSSLoad: 742 return "Extended BSS Load" 743 case Dot11InformationElementIDWideBWChannelSwitch: 744 return "Wide Bandwidth Channel Switch" 745 case Dot11InformationElementIDVHTTxPowerEnvelope: 746 return "VHT Tx Power Envelope (IEEE Std 802.11ac/D5.0)" 747 case Dot11InformationElementIDChannelSwitchWrapper: 748 return "Channel Switch Wrapper" 749 case Dot11InformationElementIDOperatingModeNotification: 750 return "Operating Mode Notification" 751 case Dot11InformationElementIDUPSIM: 752 return "UP SIM" 753 case Dot11InformationElementIDReducedNeighborReport: 754 return "Reduced Neighbor Report" 755 case Dot11InformationElementIDTVHTOperation: 756 return "TVHT Op" 757 case Dot11InformationElementIDDeviceLocation: 758 return "Device Location" 759 case Dot11InformationElementIDWhiteSpaceMap: 760 return "White Space Map" 761 case Dot11InformationElementIDFineTuningMeasureParams: 762 return "Fine Tuning Measure Parameters" 763 case Dot11InformationElementIDVendor: 764 return "Vendor" 765 default: 766 return "Unknown information element id" 767 } 768} 769 770// Dot11 provides an IEEE 802.11 base packet header. 771// See http://standards.ieee.org/findstds/standard/802.11-2012.html 772// for excruciating detail. 773type Dot11 struct { 774 BaseLayer 775 Type Dot11Type 776 Proto uint8 777 Flags Dot11Flags 778 DurationID uint16 779 Address1 net.HardwareAddr 780 Address2 net.HardwareAddr 781 Address3 net.HardwareAddr 782 Address4 net.HardwareAddr 783 SequenceNumber uint16 784 FragmentNumber uint16 785 Checksum uint32 786 QOS *Dot11QOS 787 HTControl *Dot11HTControl 788 DataLayer gopacket.Layer 789} 790 791type Dot11QOS struct { 792 TID uint8 /* Traffic IDentifier */ 793 EOSP bool /* End of service period */ 794 AckPolicy Dot11AckPolicy 795 TXOP uint8 796} 797 798type Dot11HTControl struct { 799 ACConstraint bool 800 RDGMorePPDU bool 801 802 VHT *Dot11HTControlVHT 803 HT *Dot11HTControlHT 804} 805 806type Dot11HTControlHT struct { 807 LinkAdapationControl *Dot11LinkAdapationControl 808 CalibrationPosition uint8 809 CalibrationSequence uint8 810 CSISteering uint8 811 NDPAnnouncement bool 812 DEI bool 813} 814 815type Dot11HTControlVHT struct { 816 MRQ bool 817 UnsolicitedMFB bool 818 MSI *uint8 819 MFB Dot11HTControlMFB 820 CompressedMSI *uint8 821 STBCIndication bool 822 MFSI *uint8 823 GID *uint8 824 CodingType *Dot11CodingType 825 FbTXBeamformed bool 826} 827 828type Dot11HTControlMFB struct { 829 NumSTS uint8 830 VHTMCS uint8 831 BW uint8 832 SNR int8 833} 834 835type Dot11LinkAdapationControl struct { 836 TRQ bool 837 MRQ bool 838 MSI uint8 839 MFSI uint8 840 ASEL *Dot11ASEL 841 MFB *uint8 842} 843 844type Dot11ASEL struct { 845 Command uint8 846 Data uint8 847} 848 849type Dot11CodingType uint8 850 851const ( 852 Dot11CodingTypeBCC = 0 853 Dot11CodingTypeLDPC = 1 854) 855 856func (a Dot11CodingType) String() string { 857 switch a { 858 case Dot11CodingTypeBCC: 859 return "BCC" 860 case Dot11CodingTypeLDPC: 861 return "LDPC" 862 default: 863 return "Unknown coding type" 864 } 865} 866 867func (m *Dot11HTControlMFB) NoFeedBackPresent() bool { 868 return m.VHTMCS == 15 && m.NumSTS == 7 869} 870 871func decodeDot11(data []byte, p gopacket.PacketBuilder) error { 872 d := &Dot11{} 873 err := d.DecodeFromBytes(data, p) 874 if err != nil { 875 return err 876 } 877 p.AddLayer(d) 878 if d.DataLayer != nil { 879 p.AddLayer(d.DataLayer) 880 } 881 return p.NextDecoder(d.NextLayerType()) 882} 883 884func (m *Dot11) LayerType() gopacket.LayerType { return LayerTypeDot11 } 885func (m *Dot11) CanDecode() gopacket.LayerClass { return LayerTypeDot11 } 886func (m *Dot11) NextLayerType() gopacket.LayerType { 887 if m.DataLayer != nil { 888 if m.Flags.WEP() { 889 return LayerTypeDot11WEP 890 } 891 return m.DataLayer.(gopacket.DecodingLayer).NextLayerType() 892 } 893 return m.Type.LayerType() 894} 895 896func createU8(x uint8) *uint8 { 897 return &x 898} 899 900var dataDecodeMap = map[Dot11Type]func() gopacket.DecodingLayer{ 901 Dot11TypeData: func() gopacket.DecodingLayer { return &Dot11Data{} }, 902 Dot11TypeDataCFAck: func() gopacket.DecodingLayer { return &Dot11DataCFAck{} }, 903 Dot11TypeDataCFPoll: func() gopacket.DecodingLayer { return &Dot11DataCFPoll{} }, 904 Dot11TypeDataCFAckPoll: func() gopacket.DecodingLayer { return &Dot11DataCFAckPoll{} }, 905 Dot11TypeDataNull: func() gopacket.DecodingLayer { return &Dot11DataNull{} }, 906 Dot11TypeDataCFAckNoData: func() gopacket.DecodingLayer { return &Dot11DataCFAckNoData{} }, 907 Dot11TypeDataCFPollNoData: func() gopacket.DecodingLayer { return &Dot11DataCFPollNoData{} }, 908 Dot11TypeDataCFAckPollNoData: func() gopacket.DecodingLayer { return &Dot11DataCFAckPollNoData{} }, 909 Dot11TypeDataQOSData: func() gopacket.DecodingLayer { return &Dot11DataQOSData{} }, 910 Dot11TypeDataQOSDataCFAck: func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFAck{} }, 911 Dot11TypeDataQOSDataCFPoll: func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFPoll{} }, 912 Dot11TypeDataQOSDataCFAckPoll: func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFAckPoll{} }, 913 Dot11TypeDataQOSNull: func() gopacket.DecodingLayer { return &Dot11DataQOSNull{} }, 914 Dot11TypeDataQOSCFPollNoData: func() gopacket.DecodingLayer { return &Dot11DataQOSCFPollNoData{} }, 915 Dot11TypeDataQOSCFAckPollNoData: func() gopacket.DecodingLayer { return &Dot11DataQOSCFAckPollNoData{} }, 916} 917 918func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 919 if len(data) < 10 { 920 df.SetTruncated() 921 return fmt.Errorf("Dot11 length %v too short, %v required", len(data), 10) 922 } 923 m.Type = Dot11Type((data[0])&0xFC) >> 2 924 925 m.DataLayer = nil 926 m.Proto = uint8(data[0]) & 0x0003 927 m.Flags = Dot11Flags(data[1]) 928 m.DurationID = binary.LittleEndian.Uint16(data[2:4]) 929 m.Address1 = net.HardwareAddr(data[4:10]) 930 931 offset := 10 932 933 mainType := m.Type.MainType() 934 935 switch mainType { 936 case Dot11TypeCtrl: 937 switch m.Type { 938 case Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck: 939 if len(data) < offset+6 { 940 df.SetTruncated() 941 return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) 942 } 943 m.Address2 = net.HardwareAddr(data[offset : offset+6]) 944 offset += 6 945 } 946 case Dot11TypeMgmt, Dot11TypeData: 947 if len(data) < offset+14 { 948 df.SetTruncated() 949 return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+14) 950 } 951 m.Address2 = net.HardwareAddr(data[offset : offset+6]) 952 offset += 6 953 m.Address3 = net.HardwareAddr(data[offset : offset+6]) 954 offset += 6 955 956 m.SequenceNumber = (binary.LittleEndian.Uint16(data[offset:offset+2]) & 0xFFF0) >> 4 957 m.FragmentNumber = (binary.LittleEndian.Uint16(data[offset:offset+2]) & 0x000F) 958 offset += 2 959 } 960 961 if mainType == Dot11TypeData && m.Flags.FromDS() && m.Flags.ToDS() { 962 if len(data) < offset+6 { 963 df.SetTruncated() 964 return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) 965 } 966 m.Address4 = net.HardwareAddr(data[offset : offset+6]) 967 offset += 6 968 } 969 970 if m.Type.QOS() { 971 if len(data) < offset+2 { 972 df.SetTruncated() 973 return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) 974 } 975 m.QOS = &Dot11QOS{ 976 TID: (uint8(data[offset]) & 0x0F), 977 EOSP: (uint8(data[offset]) & 0x10) == 0x10, 978 AckPolicy: Dot11AckPolicy((uint8(data[offset]) & 0x60) >> 5), 979 TXOP: uint8(data[offset+1]), 980 } 981 offset += 2 982 } 983 if m.Flags.Order() && (m.Type.QOS() || mainType == Dot11TypeMgmt) { 984 if len(data) < offset+4 { 985 df.SetTruncated() 986 return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) 987 } 988 989 htc := &Dot11HTControl{ 990 ACConstraint: data[offset+3]&0x40 != 0, 991 RDGMorePPDU: data[offset+3]&0x80 != 0, 992 } 993 m.HTControl = htc 994 995 if data[offset]&0x1 != 0 { // VHT Variant 996 vht := &Dot11HTControlVHT{} 997 htc.VHT = vht 998 vht.MRQ = data[offset]&0x4 != 0 999 vht.UnsolicitedMFB = data[offset+3]&0x20 != 0 1000 vht.MFB = Dot11HTControlMFB{ 1001 NumSTS: uint8(data[offset+1] >> 1 & 0x7), 1002 VHTMCS: uint8(data[offset+1] >> 4 & 0xF), 1003 BW: uint8(data[offset+2] & 0x3), 1004 SNR: int8((-(data[offset+2] >> 2 & 0x20))+data[offset+2]>>2&0x1F) + 22, 1005 } 1006 1007 if vht.UnsolicitedMFB { 1008 if !vht.MFB.NoFeedBackPresent() { 1009 vht.CompressedMSI = createU8(data[offset] >> 3 & 0x3) 1010 vht.STBCIndication = data[offset]&0x20 != 0 1011 vht.CodingType = (*Dot11CodingType)(createU8(data[offset+3] >> 3 & 0x1)) 1012 vht.FbTXBeamformed = data[offset+3]&0x10 != 0 1013 vht.GID = createU8( 1014 data[offset]>>6 + 1015 (data[offset+1] & 0x1 << 2) + 1016 data[offset+3]&0x7<<3) 1017 } 1018 } else { 1019 if vht.MRQ { 1020 vht.MSI = createU8((data[offset] >> 3) & 0x07) 1021 } 1022 vht.MFSI = createU8(data[offset]>>6 + (data[offset+1] & 0x1 << 2)) 1023 } 1024 1025 } else { // HT Variant 1026 ht := &Dot11HTControlHT{} 1027 htc.HT = ht 1028 1029 lac := &Dot11LinkAdapationControl{} 1030 ht.LinkAdapationControl = lac 1031 lac.TRQ = data[offset]&0x2 != 0 1032 lac.MFSI = data[offset]>>6&0x3 + data[offset+1]&0x1<<3 1033 if data[offset]&0x3C == 0x38 { // ASEL 1034 lac.ASEL = &Dot11ASEL{ 1035 Command: data[offset+1] >> 1 & 0x7, 1036 Data: data[offset+1] >> 4 & 0xF, 1037 } 1038 } else { 1039 lac.MRQ = data[offset]&0x4 != 0 1040 if lac.MRQ { 1041 lac.MSI = data[offset] >> 3 & 0x7 1042 } 1043 lac.MFB = createU8(data[offset+1] >> 1) 1044 } 1045 ht.CalibrationPosition = data[offset+2] & 0x3 1046 ht.CalibrationSequence = data[offset+2] >> 2 & 0x3 1047 ht.CSISteering = data[offset+2] >> 6 & 0x3 1048 ht.NDPAnnouncement = data[offset+3]&0x1 != 0 1049 if mainType != Dot11TypeMgmt { 1050 ht.DEI = data[offset+3]&0x20 != 0 1051 } 1052 } 1053 1054 offset += 4 1055 } 1056 1057 if len(data) < offset+4 { 1058 df.SetTruncated() 1059 return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+4) 1060 } 1061 1062 m.BaseLayer = BaseLayer{ 1063 Contents: data[0:offset], 1064 Payload: data[offset : len(data)-4], 1065 } 1066 1067 if mainType == Dot11TypeData { 1068 d := dataDecodeMap[m.Type] 1069 if d == nil { 1070 return fmt.Errorf("unsupported type: %v", m.Type) 1071 } 1072 l := d() 1073 err := l.DecodeFromBytes(m.BaseLayer.Payload, df) 1074 if err != nil { 1075 return err 1076 } 1077 m.DataLayer = l.(gopacket.Layer) 1078 } 1079 1080 m.Checksum = binary.LittleEndian.Uint32(data[len(data)-4 : len(data)]) 1081 return nil 1082} 1083 1084func (m *Dot11) ChecksumValid() bool { 1085 // only for CTRL and MGMT frames 1086 h := crc32.NewIEEE() 1087 h.Write(m.Contents) 1088 h.Write(m.Payload) 1089 return m.Checksum == h.Sum32() 1090} 1091 1092func (m Dot11) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 1093 buf, err := b.PrependBytes(24) 1094 1095 if err != nil { 1096 return err 1097 } 1098 1099 buf[0] = (uint8(m.Type) << 2) | m.Proto 1100 buf[1] = uint8(m.Flags) 1101 1102 binary.LittleEndian.PutUint16(buf[2:4], m.DurationID) 1103 1104 copy(buf[4:10], m.Address1) 1105 1106 offset := 10 1107 1108 switch m.Type.MainType() { 1109 case Dot11TypeCtrl: 1110 switch m.Type { 1111 case Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck: 1112 copy(buf[offset:offset+6], m.Address2) 1113 offset += 6 1114 } 1115 case Dot11TypeMgmt, Dot11TypeData: 1116 copy(buf[offset:offset+6], m.Address2) 1117 offset += 6 1118 copy(buf[offset:offset+6], m.Address3) 1119 offset += 6 1120 1121 binary.LittleEndian.PutUint16(buf[offset:offset+2], (m.SequenceNumber<<4)|m.FragmentNumber) 1122 offset += 2 1123 } 1124 1125 if m.Type.MainType() == Dot11TypeData && m.Flags.FromDS() && m.Flags.ToDS() { 1126 copy(buf[offset:offset+6], m.Address4) 1127 offset += 6 1128 } 1129 1130 return nil 1131} 1132 1133// Dot11Mgmt is a base for all IEEE 802.11 management layers. 1134type Dot11Mgmt struct { 1135 BaseLayer 1136} 1137 1138func (m *Dot11Mgmt) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } 1139func (m *Dot11Mgmt) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1140 m.Contents = data 1141 return nil 1142} 1143 1144// Dot11Ctrl is a base for all IEEE 802.11 control layers. 1145type Dot11Ctrl struct { 1146 BaseLayer 1147} 1148 1149func (m *Dot11Ctrl) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } 1150 1151func (m *Dot11Ctrl) LayerType() gopacket.LayerType { return LayerTypeDot11Ctrl } 1152func (m *Dot11Ctrl) CanDecode() gopacket.LayerClass { return LayerTypeDot11Ctrl } 1153func (m *Dot11Ctrl) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1154 m.Contents = data 1155 return nil 1156} 1157 1158func decodeDot11Ctrl(data []byte, p gopacket.PacketBuilder) error { 1159 d := &Dot11Ctrl{} 1160 return decodingLayerDecoder(d, data, p) 1161} 1162 1163// Dot11WEP contains WEP encrpted IEEE 802.11 data. 1164type Dot11WEP struct { 1165 BaseLayer 1166} 1167 1168func (m *Dot11WEP) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } 1169 1170func (m *Dot11WEP) LayerType() gopacket.LayerType { return LayerTypeDot11WEP } 1171func (m *Dot11WEP) CanDecode() gopacket.LayerClass { return LayerTypeDot11WEP } 1172func (m *Dot11WEP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1173 m.Contents = data 1174 return nil 1175} 1176 1177func decodeDot11WEP(data []byte, p gopacket.PacketBuilder) error { 1178 d := &Dot11WEP{} 1179 return decodingLayerDecoder(d, data, p) 1180} 1181 1182// Dot11Data is a base for all IEEE 802.11 data layers. 1183type Dot11Data struct { 1184 BaseLayer 1185} 1186 1187func (m *Dot11Data) NextLayerType() gopacket.LayerType { 1188 return LayerTypeLLC 1189} 1190 1191func (m *Dot11Data) LayerType() gopacket.LayerType { return LayerTypeDot11Data } 1192func (m *Dot11Data) CanDecode() gopacket.LayerClass { return LayerTypeDot11Data } 1193func (m *Dot11Data) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1194 m.Payload = data 1195 return nil 1196} 1197 1198func decodeDot11Data(data []byte, p gopacket.PacketBuilder) error { 1199 d := &Dot11Data{} 1200 return decodingLayerDecoder(d, data, p) 1201} 1202 1203type Dot11DataCFAck struct { 1204 Dot11Data 1205} 1206 1207func decodeDot11DataCFAck(data []byte, p gopacket.PacketBuilder) error { 1208 d := &Dot11DataCFAck{} 1209 return decodingLayerDecoder(d, data, p) 1210} 1211 1212func (m *Dot11DataCFAck) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAck } 1213func (m *Dot11DataCFAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAck } 1214func (m *Dot11DataCFAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1215 return m.Dot11Data.DecodeFromBytes(data, df) 1216} 1217 1218type Dot11DataCFPoll struct { 1219 Dot11Data 1220} 1221 1222func decodeDot11DataCFPoll(data []byte, p gopacket.PacketBuilder) error { 1223 d := &Dot11DataCFPoll{} 1224 return decodingLayerDecoder(d, data, p) 1225} 1226 1227func (m *Dot11DataCFPoll) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFPoll } 1228func (m *Dot11DataCFPoll) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFPoll } 1229func (m *Dot11DataCFPoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1230 return m.Dot11Data.DecodeFromBytes(data, df) 1231} 1232 1233type Dot11DataCFAckPoll struct { 1234 Dot11Data 1235} 1236 1237func decodeDot11DataCFAckPoll(data []byte, p gopacket.PacketBuilder) error { 1238 d := &Dot11DataCFAckPoll{} 1239 return decodingLayerDecoder(d, data, p) 1240} 1241 1242func (m *Dot11DataCFAckPoll) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAckPoll } 1243func (m *Dot11DataCFAckPoll) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAckPoll } 1244func (m *Dot11DataCFAckPoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1245 return m.Dot11Data.DecodeFromBytes(data, df) 1246} 1247 1248type Dot11DataNull struct { 1249 Dot11Data 1250} 1251 1252func decodeDot11DataNull(data []byte, p gopacket.PacketBuilder) error { 1253 d := &Dot11DataNull{} 1254 return decodingLayerDecoder(d, data, p) 1255} 1256 1257func (m *Dot11DataNull) LayerType() gopacket.LayerType { return LayerTypeDot11DataNull } 1258func (m *Dot11DataNull) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataNull } 1259func (m *Dot11DataNull) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1260 return m.Dot11Data.DecodeFromBytes(data, df) 1261} 1262 1263type Dot11DataCFAckNoData struct { 1264 Dot11Data 1265} 1266 1267func decodeDot11DataCFAckNoData(data []byte, p gopacket.PacketBuilder) error { 1268 d := &Dot11DataCFAckNoData{} 1269 return decodingLayerDecoder(d, data, p) 1270} 1271 1272func (m *Dot11DataCFAckNoData) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAckNoData } 1273func (m *Dot11DataCFAckNoData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAckNoData } 1274func (m *Dot11DataCFAckNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1275 return m.Dot11Data.DecodeFromBytes(data, df) 1276} 1277 1278type Dot11DataCFPollNoData struct { 1279 Dot11Data 1280} 1281 1282func decodeDot11DataCFPollNoData(data []byte, p gopacket.PacketBuilder) error { 1283 d := &Dot11DataCFPollNoData{} 1284 return decodingLayerDecoder(d, data, p) 1285} 1286 1287func (m *Dot11DataCFPollNoData) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFPollNoData } 1288func (m *Dot11DataCFPollNoData) CanDecode() gopacket.LayerClass { 1289 return LayerTypeDot11DataCFPollNoData 1290} 1291func (m *Dot11DataCFPollNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1292 return m.Dot11Data.DecodeFromBytes(data, df) 1293} 1294 1295type Dot11DataCFAckPollNoData struct { 1296 Dot11Data 1297} 1298 1299func decodeDot11DataCFAckPollNoData(data []byte, p gopacket.PacketBuilder) error { 1300 d := &Dot11DataCFAckPollNoData{} 1301 return decodingLayerDecoder(d, data, p) 1302} 1303 1304func (m *Dot11DataCFAckPollNoData) LayerType() gopacket.LayerType { 1305 return LayerTypeDot11DataCFAckPollNoData 1306} 1307func (m *Dot11DataCFAckPollNoData) CanDecode() gopacket.LayerClass { 1308 return LayerTypeDot11DataCFAckPollNoData 1309} 1310func (m *Dot11DataCFAckPollNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1311 return m.Dot11Data.DecodeFromBytes(data, df) 1312} 1313 1314type Dot11DataQOS struct { 1315 Dot11Ctrl 1316} 1317 1318func (m *Dot11DataQOS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1319 m.BaseLayer = BaseLayer{Payload: data} 1320 return nil 1321} 1322 1323type Dot11DataQOSData struct { 1324 Dot11DataQOS 1325} 1326 1327func decodeDot11DataQOSData(data []byte, p gopacket.PacketBuilder) error { 1328 d := &Dot11DataQOSData{} 1329 return decodingLayerDecoder(d, data, p) 1330} 1331 1332func (m *Dot11DataQOSData) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSData } 1333func (m *Dot11DataQOSData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSData } 1334 1335func (m *Dot11DataQOSData) NextLayerType() gopacket.LayerType { 1336 return LayerTypeDot11Data 1337} 1338 1339type Dot11DataQOSDataCFAck struct { 1340 Dot11DataQOS 1341} 1342 1343func decodeDot11DataQOSDataCFAck(data []byte, p gopacket.PacketBuilder) error { 1344 d := &Dot11DataQOSDataCFAck{} 1345 return decodingLayerDecoder(d, data, p) 1346} 1347 1348func (m *Dot11DataQOSDataCFAck) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSDataCFAck } 1349func (m *Dot11DataQOSDataCFAck) CanDecode() gopacket.LayerClass { 1350 return LayerTypeDot11DataQOSDataCFAck 1351} 1352func (m *Dot11DataQOSDataCFAck) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataCFAck } 1353 1354type Dot11DataQOSDataCFPoll struct { 1355 Dot11DataQOS 1356} 1357 1358func decodeDot11DataQOSDataCFPoll(data []byte, p gopacket.PacketBuilder) error { 1359 d := &Dot11DataQOSDataCFPoll{} 1360 return decodingLayerDecoder(d, data, p) 1361} 1362 1363func (m *Dot11DataQOSDataCFPoll) LayerType() gopacket.LayerType { 1364 return LayerTypeDot11DataQOSDataCFPoll 1365} 1366func (m *Dot11DataQOSDataCFPoll) CanDecode() gopacket.LayerClass { 1367 return LayerTypeDot11DataQOSDataCFPoll 1368} 1369func (m *Dot11DataQOSDataCFPoll) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataCFPoll } 1370 1371type Dot11DataQOSDataCFAckPoll struct { 1372 Dot11DataQOS 1373} 1374 1375func decodeDot11DataQOSDataCFAckPoll(data []byte, p gopacket.PacketBuilder) error { 1376 d := &Dot11DataQOSDataCFAckPoll{} 1377 return decodingLayerDecoder(d, data, p) 1378} 1379 1380func (m *Dot11DataQOSDataCFAckPoll) LayerType() gopacket.LayerType { 1381 return LayerTypeDot11DataQOSDataCFAckPoll 1382} 1383func (m *Dot11DataQOSDataCFAckPoll) CanDecode() gopacket.LayerClass { 1384 return LayerTypeDot11DataQOSDataCFAckPoll 1385} 1386func (m *Dot11DataQOSDataCFAckPoll) NextLayerType() gopacket.LayerType { 1387 return LayerTypeDot11DataCFAckPoll 1388} 1389 1390type Dot11DataQOSNull struct { 1391 Dot11DataQOS 1392} 1393 1394func decodeDot11DataQOSNull(data []byte, p gopacket.PacketBuilder) error { 1395 d := &Dot11DataQOSNull{} 1396 return decodingLayerDecoder(d, data, p) 1397} 1398 1399func (m *Dot11DataQOSNull) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSNull } 1400func (m *Dot11DataQOSNull) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSNull } 1401func (m *Dot11DataQOSNull) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataNull } 1402 1403type Dot11DataQOSCFPollNoData struct { 1404 Dot11DataQOS 1405} 1406 1407func decodeDot11DataQOSCFPollNoData(data []byte, p gopacket.PacketBuilder) error { 1408 d := &Dot11DataQOSCFPollNoData{} 1409 return decodingLayerDecoder(d, data, p) 1410} 1411 1412func (m *Dot11DataQOSCFPollNoData) LayerType() gopacket.LayerType { 1413 return LayerTypeDot11DataQOSCFPollNoData 1414} 1415func (m *Dot11DataQOSCFPollNoData) CanDecode() gopacket.LayerClass { 1416 return LayerTypeDot11DataQOSCFPollNoData 1417} 1418func (m *Dot11DataQOSCFPollNoData) NextLayerType() gopacket.LayerType { 1419 return LayerTypeDot11DataCFPollNoData 1420} 1421 1422type Dot11DataQOSCFAckPollNoData struct { 1423 Dot11DataQOS 1424} 1425 1426func decodeDot11DataQOSCFAckPollNoData(data []byte, p gopacket.PacketBuilder) error { 1427 d := &Dot11DataQOSCFAckPollNoData{} 1428 return decodingLayerDecoder(d, data, p) 1429} 1430 1431func (m *Dot11DataQOSCFAckPollNoData) LayerType() gopacket.LayerType { 1432 return LayerTypeDot11DataQOSCFAckPollNoData 1433} 1434func (m *Dot11DataQOSCFAckPollNoData) CanDecode() gopacket.LayerClass { 1435 return LayerTypeDot11DataQOSCFAckPollNoData 1436} 1437func (m *Dot11DataQOSCFAckPollNoData) NextLayerType() gopacket.LayerType { 1438 return LayerTypeDot11DataCFAckPollNoData 1439} 1440 1441type Dot11InformationElement struct { 1442 BaseLayer 1443 ID Dot11InformationElementID 1444 Length uint8 1445 OUI []byte 1446 Info []byte 1447} 1448 1449func (m *Dot11InformationElement) LayerType() gopacket.LayerType { 1450 return LayerTypeDot11InformationElement 1451} 1452func (m *Dot11InformationElement) CanDecode() gopacket.LayerClass { 1453 return LayerTypeDot11InformationElement 1454} 1455 1456func (m *Dot11InformationElement) NextLayerType() gopacket.LayerType { 1457 return LayerTypeDot11InformationElement 1458} 1459 1460func (m *Dot11InformationElement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1461 if len(data) < 2 { 1462 df.SetTruncated() 1463 return fmt.Errorf("Dot11InformationElement length %v too short, %v required", len(data), 2) 1464 } 1465 m.ID = Dot11InformationElementID(data[0]) 1466 m.Length = data[1] 1467 offset := int(2) 1468 1469 if len(data) < offset+int(m.Length) { 1470 df.SetTruncated() 1471 return fmt.Errorf("Dot11InformationElement length %v too short, %v required", len(data), offset+int(m.Length)) 1472 } 1473 if len(data) < offset+4 { 1474 df.SetTruncated() 1475 return fmt.Errorf("vendor extension size < %d", offset+int(m.Length)) 1476 } 1477 if m.ID == 221 { 1478 // Vendor extension 1479 m.OUI = data[offset : offset+4] 1480 m.Info = data[offset+4 : offset+int(m.Length)] 1481 } else { 1482 m.Info = data[offset : offset+int(m.Length)] 1483 } 1484 1485 offset += int(m.Length) 1486 1487 m.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]} 1488 return nil 1489} 1490 1491func (d *Dot11InformationElement) String() string { 1492 if d.ID == 0 { 1493 return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, SSID: %v)", d.ID, d.Length, string(d.Info)) 1494 } else if d.ID == 1 { 1495 rates := "" 1496 for i := 0; i < len(d.Info); i++ { 1497 if d.Info[i]&0x80 == 0 { 1498 rates += fmt.Sprintf("%.1f ", float32(d.Info[i])*0.5) 1499 } else { 1500 rates += fmt.Sprintf("%.1f* ", float32(d.Info[i]&0x7F)*0.5) 1501 } 1502 } 1503 return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Rates: %s Mbit)", d.ID, d.Length, rates) 1504 } else if d.ID == 221 { 1505 return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, OUI: %X, Info: %X)", d.ID, d.Length, d.OUI, d.Info) 1506 } else { 1507 return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Info: %X)", d.ID, d.Length, d.Info) 1508 } 1509} 1510 1511func (m Dot11InformationElement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 1512 length := len(m.Info) + len(m.OUI) 1513 if buf, err := b.PrependBytes(2 + length); err != nil { 1514 return err 1515 } else { 1516 buf[0] = uint8(m.ID) 1517 buf[1] = uint8(length) 1518 copy(buf[2:], m.OUI) 1519 copy(buf[2+len(m.OUI):], m.Info) 1520 } 1521 return nil 1522} 1523 1524func decodeDot11InformationElement(data []byte, p gopacket.PacketBuilder) error { 1525 d := &Dot11InformationElement{} 1526 return decodingLayerDecoder(d, data, p) 1527} 1528 1529type Dot11CtrlCTS struct { 1530 Dot11Ctrl 1531} 1532 1533func decodeDot11CtrlCTS(data []byte, p gopacket.PacketBuilder) error { 1534 d := &Dot11CtrlCTS{} 1535 return decodingLayerDecoder(d, data, p) 1536} 1537 1538func (m *Dot11CtrlCTS) LayerType() gopacket.LayerType { 1539 return LayerTypeDot11CtrlCTS 1540} 1541func (m *Dot11CtrlCTS) CanDecode() gopacket.LayerClass { 1542 return LayerTypeDot11CtrlCTS 1543} 1544func (m *Dot11CtrlCTS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1545 return m.Dot11Ctrl.DecodeFromBytes(data, df) 1546} 1547 1548type Dot11CtrlRTS struct { 1549 Dot11Ctrl 1550} 1551 1552func decodeDot11CtrlRTS(data []byte, p gopacket.PacketBuilder) error { 1553 d := &Dot11CtrlRTS{} 1554 return decodingLayerDecoder(d, data, p) 1555} 1556 1557func (m *Dot11CtrlRTS) LayerType() gopacket.LayerType { 1558 return LayerTypeDot11CtrlRTS 1559} 1560func (m *Dot11CtrlRTS) CanDecode() gopacket.LayerClass { 1561 return LayerTypeDot11CtrlRTS 1562} 1563func (m *Dot11CtrlRTS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1564 return m.Dot11Ctrl.DecodeFromBytes(data, df) 1565} 1566 1567type Dot11CtrlBlockAckReq struct { 1568 Dot11Ctrl 1569} 1570 1571func decodeDot11CtrlBlockAckReq(data []byte, p gopacket.PacketBuilder) error { 1572 d := &Dot11CtrlBlockAckReq{} 1573 return decodingLayerDecoder(d, data, p) 1574} 1575 1576func (m *Dot11CtrlBlockAckReq) LayerType() gopacket.LayerType { 1577 return LayerTypeDot11CtrlBlockAckReq 1578} 1579func (m *Dot11CtrlBlockAckReq) CanDecode() gopacket.LayerClass { 1580 return LayerTypeDot11CtrlBlockAckReq 1581} 1582func (m *Dot11CtrlBlockAckReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1583 return m.Dot11Ctrl.DecodeFromBytes(data, df) 1584} 1585 1586type Dot11CtrlBlockAck struct { 1587 Dot11Ctrl 1588} 1589 1590func decodeDot11CtrlBlockAck(data []byte, p gopacket.PacketBuilder) error { 1591 d := &Dot11CtrlBlockAck{} 1592 return decodingLayerDecoder(d, data, p) 1593} 1594 1595func (m *Dot11CtrlBlockAck) LayerType() gopacket.LayerType { return LayerTypeDot11CtrlBlockAck } 1596func (m *Dot11CtrlBlockAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11CtrlBlockAck } 1597func (m *Dot11CtrlBlockAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1598 return m.Dot11Ctrl.DecodeFromBytes(data, df) 1599} 1600 1601type Dot11CtrlPowersavePoll struct { 1602 Dot11Ctrl 1603} 1604 1605func decodeDot11CtrlPowersavePoll(data []byte, p gopacket.PacketBuilder) error { 1606 d := &Dot11CtrlPowersavePoll{} 1607 return decodingLayerDecoder(d, data, p) 1608} 1609 1610func (m *Dot11CtrlPowersavePoll) LayerType() gopacket.LayerType { 1611 return LayerTypeDot11CtrlPowersavePoll 1612} 1613func (m *Dot11CtrlPowersavePoll) CanDecode() gopacket.LayerClass { 1614 return LayerTypeDot11CtrlPowersavePoll 1615} 1616func (m *Dot11CtrlPowersavePoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1617 return m.Dot11Ctrl.DecodeFromBytes(data, df) 1618} 1619 1620type Dot11CtrlAck struct { 1621 Dot11Ctrl 1622} 1623 1624func decodeDot11CtrlAck(data []byte, p gopacket.PacketBuilder) error { 1625 d := &Dot11CtrlAck{} 1626 return decodingLayerDecoder(d, data, p) 1627} 1628 1629func (m *Dot11CtrlAck) LayerType() gopacket.LayerType { return LayerTypeDot11CtrlAck } 1630func (m *Dot11CtrlAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11CtrlAck } 1631func (m *Dot11CtrlAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1632 return m.Dot11Ctrl.DecodeFromBytes(data, df) 1633} 1634 1635type Dot11CtrlCFEnd struct { 1636 Dot11Ctrl 1637} 1638 1639func decodeDot11CtrlCFEnd(data []byte, p gopacket.PacketBuilder) error { 1640 d := &Dot11CtrlCFEnd{} 1641 return decodingLayerDecoder(d, data, p) 1642} 1643 1644func (m *Dot11CtrlCFEnd) LayerType() gopacket.LayerType { 1645 return LayerTypeDot11CtrlCFEnd 1646} 1647func (m *Dot11CtrlCFEnd) CanDecode() gopacket.LayerClass { 1648 return LayerTypeDot11CtrlCFEnd 1649} 1650func (m *Dot11CtrlCFEnd) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1651 return m.Dot11Ctrl.DecodeFromBytes(data, df) 1652} 1653 1654type Dot11CtrlCFEndAck struct { 1655 Dot11Ctrl 1656} 1657 1658func decodeDot11CtrlCFEndAck(data []byte, p gopacket.PacketBuilder) error { 1659 d := &Dot11CtrlCFEndAck{} 1660 return decodingLayerDecoder(d, data, p) 1661} 1662 1663func (m *Dot11CtrlCFEndAck) LayerType() gopacket.LayerType { 1664 return LayerTypeDot11CtrlCFEndAck 1665} 1666func (m *Dot11CtrlCFEndAck) CanDecode() gopacket.LayerClass { 1667 return LayerTypeDot11CtrlCFEndAck 1668} 1669func (m *Dot11CtrlCFEndAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1670 return m.Dot11Ctrl.DecodeFromBytes(data, df) 1671} 1672 1673type Dot11MgmtAssociationReq struct { 1674 Dot11Mgmt 1675 CapabilityInfo uint16 1676 ListenInterval uint16 1677} 1678 1679func decodeDot11MgmtAssociationReq(data []byte, p gopacket.PacketBuilder) error { 1680 d := &Dot11MgmtAssociationReq{} 1681 return decodingLayerDecoder(d, data, p) 1682} 1683 1684func (m *Dot11MgmtAssociationReq) LayerType() gopacket.LayerType { 1685 return LayerTypeDot11MgmtAssociationReq 1686} 1687func (m *Dot11MgmtAssociationReq) CanDecode() gopacket.LayerClass { 1688 return LayerTypeDot11MgmtAssociationReq 1689} 1690func (m *Dot11MgmtAssociationReq) NextLayerType() gopacket.LayerType { 1691 return LayerTypeDot11InformationElement 1692} 1693func (m *Dot11MgmtAssociationReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1694 if len(data) < 4 { 1695 df.SetTruncated() 1696 return fmt.Errorf("Dot11MgmtAssociationReq length %v too short, %v required", len(data), 4) 1697 } 1698 m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) 1699 m.ListenInterval = binary.LittleEndian.Uint16(data[2:4]) 1700 m.Payload = data[4:] 1701 return m.Dot11Mgmt.DecodeFromBytes(data, df) 1702} 1703 1704func (m Dot11MgmtAssociationReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 1705 buf, err := b.PrependBytes(4) 1706 1707 if err != nil { 1708 return err 1709 } 1710 1711 binary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo) 1712 binary.LittleEndian.PutUint16(buf[2:4], m.ListenInterval) 1713 1714 return nil 1715} 1716 1717type Dot11MgmtAssociationResp struct { 1718 Dot11Mgmt 1719 CapabilityInfo uint16 1720 Status Dot11Status 1721 AID uint16 1722} 1723 1724func decodeDot11MgmtAssociationResp(data []byte, p gopacket.PacketBuilder) error { 1725 d := &Dot11MgmtAssociationResp{} 1726 return decodingLayerDecoder(d, data, p) 1727} 1728 1729func (m *Dot11MgmtAssociationResp) CanDecode() gopacket.LayerClass { 1730 return LayerTypeDot11MgmtAssociationResp 1731} 1732func (m *Dot11MgmtAssociationResp) LayerType() gopacket.LayerType { 1733 return LayerTypeDot11MgmtAssociationResp 1734} 1735func (m *Dot11MgmtAssociationResp) NextLayerType() gopacket.LayerType { 1736 return LayerTypeDot11InformationElement 1737} 1738func (m *Dot11MgmtAssociationResp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1739 if len(data) < 6 { 1740 df.SetTruncated() 1741 return fmt.Errorf("Dot11MgmtAssociationResp length %v too short, %v required", len(data), 6) 1742 } 1743 m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) 1744 m.Status = Dot11Status(binary.LittleEndian.Uint16(data[2:4])) 1745 m.AID = binary.LittleEndian.Uint16(data[4:6]) 1746 m.Payload = data[6:] 1747 return m.Dot11Mgmt.DecodeFromBytes(data, df) 1748} 1749 1750func (m Dot11MgmtAssociationResp) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 1751 buf, err := b.PrependBytes(6) 1752 1753 if err != nil { 1754 return err 1755 } 1756 1757 binary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo) 1758 binary.LittleEndian.PutUint16(buf[2:4], uint16(m.Status)) 1759 binary.LittleEndian.PutUint16(buf[4:6], m.AID) 1760 1761 return nil 1762} 1763 1764type Dot11MgmtReassociationReq struct { 1765 Dot11Mgmt 1766 CapabilityInfo uint16 1767 ListenInterval uint16 1768 CurrentApAddress net.HardwareAddr 1769} 1770 1771func decodeDot11MgmtReassociationReq(data []byte, p gopacket.PacketBuilder) error { 1772 d := &Dot11MgmtReassociationReq{} 1773 return decodingLayerDecoder(d, data, p) 1774} 1775 1776func (m *Dot11MgmtReassociationReq) LayerType() gopacket.LayerType { 1777 return LayerTypeDot11MgmtReassociationReq 1778} 1779func (m *Dot11MgmtReassociationReq) CanDecode() gopacket.LayerClass { 1780 return LayerTypeDot11MgmtReassociationReq 1781} 1782func (m *Dot11MgmtReassociationReq) NextLayerType() gopacket.LayerType { 1783 return LayerTypeDot11InformationElement 1784} 1785func (m *Dot11MgmtReassociationReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1786 if len(data) < 10 { 1787 df.SetTruncated() 1788 return fmt.Errorf("Dot11MgmtReassociationReq length %v too short, %v required", len(data), 10) 1789 } 1790 m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) 1791 m.ListenInterval = binary.LittleEndian.Uint16(data[2:4]) 1792 m.CurrentApAddress = net.HardwareAddr(data[4:10]) 1793 m.Payload = data[10:] 1794 return m.Dot11Mgmt.DecodeFromBytes(data, df) 1795} 1796 1797func (m Dot11MgmtReassociationReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 1798 buf, err := b.PrependBytes(10) 1799 1800 if err != nil { 1801 return err 1802 } 1803 1804 binary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo) 1805 binary.LittleEndian.PutUint16(buf[2:4], m.ListenInterval) 1806 1807 copy(buf[4:10], m.CurrentApAddress) 1808 1809 return nil 1810} 1811 1812type Dot11MgmtReassociationResp struct { 1813 Dot11Mgmt 1814} 1815 1816func decodeDot11MgmtReassociationResp(data []byte, p gopacket.PacketBuilder) error { 1817 d := &Dot11MgmtReassociationResp{} 1818 return decodingLayerDecoder(d, data, p) 1819} 1820 1821func (m *Dot11MgmtReassociationResp) LayerType() gopacket.LayerType { 1822 return LayerTypeDot11MgmtReassociationResp 1823} 1824func (m *Dot11MgmtReassociationResp) CanDecode() gopacket.LayerClass { 1825 return LayerTypeDot11MgmtReassociationResp 1826} 1827func (m *Dot11MgmtReassociationResp) NextLayerType() gopacket.LayerType { 1828 return LayerTypeDot11InformationElement 1829} 1830 1831type Dot11MgmtProbeReq struct { 1832 Dot11Mgmt 1833} 1834 1835func decodeDot11MgmtProbeReq(data []byte, p gopacket.PacketBuilder) error { 1836 d := &Dot11MgmtProbeReq{} 1837 return decodingLayerDecoder(d, data, p) 1838} 1839 1840func (m *Dot11MgmtProbeReq) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtProbeReq } 1841func (m *Dot11MgmtProbeReq) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeReq } 1842func (m *Dot11MgmtProbeReq) NextLayerType() gopacket.LayerType { 1843 return LayerTypeDot11InformationElement 1844} 1845 1846type Dot11MgmtProbeResp struct { 1847 Dot11Mgmt 1848 Timestamp uint64 1849 Interval uint16 1850 Flags uint16 1851} 1852 1853func decodeDot11MgmtProbeResp(data []byte, p gopacket.PacketBuilder) error { 1854 d := &Dot11MgmtProbeResp{} 1855 return decodingLayerDecoder(d, data, p) 1856} 1857 1858func (m *Dot11MgmtProbeResp) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtProbeResp } 1859func (m *Dot11MgmtProbeResp) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeResp } 1860func (m *Dot11MgmtProbeResp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1861 if len(data) < 12 { 1862 df.SetTruncated() 1863 1864 return fmt.Errorf("Dot11MgmtProbeResp length %v too short, %v required", len(data), 12) 1865 } 1866 1867 m.Timestamp = binary.LittleEndian.Uint64(data[0:8]) 1868 m.Interval = binary.LittleEndian.Uint16(data[8:10]) 1869 m.Flags = binary.LittleEndian.Uint16(data[10:12]) 1870 m.Payload = data[12:] 1871 1872 return m.Dot11Mgmt.DecodeFromBytes(data, df) 1873} 1874 1875func (m *Dot11MgmtProbeResp) NextLayerType() gopacket.LayerType { 1876 return LayerTypeDot11InformationElement 1877} 1878 1879func (m Dot11MgmtProbeResp) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 1880 buf, err := b.PrependBytes(12) 1881 1882 if err != nil { 1883 return err 1884 } 1885 1886 binary.LittleEndian.PutUint64(buf[0:8], m.Timestamp) 1887 binary.LittleEndian.PutUint16(buf[8:10], m.Interval) 1888 binary.LittleEndian.PutUint16(buf[10:12], m.Flags) 1889 1890 return nil 1891} 1892 1893type Dot11MgmtMeasurementPilot struct { 1894 Dot11Mgmt 1895} 1896 1897func decodeDot11MgmtMeasurementPilot(data []byte, p gopacket.PacketBuilder) error { 1898 d := &Dot11MgmtMeasurementPilot{} 1899 return decodingLayerDecoder(d, data, p) 1900} 1901 1902func (m *Dot11MgmtMeasurementPilot) LayerType() gopacket.LayerType { 1903 return LayerTypeDot11MgmtMeasurementPilot 1904} 1905func (m *Dot11MgmtMeasurementPilot) CanDecode() gopacket.LayerClass { 1906 return LayerTypeDot11MgmtMeasurementPilot 1907} 1908 1909type Dot11MgmtBeacon struct { 1910 Dot11Mgmt 1911 Timestamp uint64 1912 Interval uint16 1913 Flags uint16 1914} 1915 1916func decodeDot11MgmtBeacon(data []byte, p gopacket.PacketBuilder) error { 1917 d := &Dot11MgmtBeacon{} 1918 return decodingLayerDecoder(d, data, p) 1919} 1920 1921func (m *Dot11MgmtBeacon) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtBeacon } 1922func (m *Dot11MgmtBeacon) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtBeacon } 1923func (m *Dot11MgmtBeacon) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1924 if len(data) < 12 { 1925 df.SetTruncated() 1926 return fmt.Errorf("Dot11MgmtBeacon length %v too short, %v required", len(data), 12) 1927 } 1928 m.Timestamp = binary.LittleEndian.Uint64(data[0:8]) 1929 m.Interval = binary.LittleEndian.Uint16(data[8:10]) 1930 m.Flags = binary.LittleEndian.Uint16(data[10:12]) 1931 m.Payload = data[12:] 1932 return m.Dot11Mgmt.DecodeFromBytes(data, df) 1933} 1934 1935func (m *Dot11MgmtBeacon) NextLayerType() gopacket.LayerType { return LayerTypeDot11InformationElement } 1936 1937func (m Dot11MgmtBeacon) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 1938 buf, err := b.PrependBytes(12) 1939 1940 if err != nil { 1941 return err 1942 } 1943 1944 binary.LittleEndian.PutUint64(buf[0:8], m.Timestamp) 1945 binary.LittleEndian.PutUint16(buf[8:10], m.Interval) 1946 binary.LittleEndian.PutUint16(buf[10:12], m.Flags) 1947 1948 return nil 1949} 1950 1951type Dot11MgmtATIM struct { 1952 Dot11Mgmt 1953} 1954 1955func decodeDot11MgmtATIM(data []byte, p gopacket.PacketBuilder) error { 1956 d := &Dot11MgmtATIM{} 1957 return decodingLayerDecoder(d, data, p) 1958} 1959 1960func (m *Dot11MgmtATIM) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtATIM } 1961func (m *Dot11MgmtATIM) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtATIM } 1962 1963type Dot11MgmtDisassociation struct { 1964 Dot11Mgmt 1965 Reason Dot11Reason 1966} 1967 1968func decodeDot11MgmtDisassociation(data []byte, p gopacket.PacketBuilder) error { 1969 d := &Dot11MgmtDisassociation{} 1970 return decodingLayerDecoder(d, data, p) 1971} 1972 1973func (m *Dot11MgmtDisassociation) LayerType() gopacket.LayerType { 1974 return LayerTypeDot11MgmtDisassociation 1975} 1976func (m *Dot11MgmtDisassociation) CanDecode() gopacket.LayerClass { 1977 return LayerTypeDot11MgmtDisassociation 1978} 1979func (m *Dot11MgmtDisassociation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 1980 if len(data) < 2 { 1981 df.SetTruncated() 1982 return fmt.Errorf("Dot11MgmtDisassociation length %v too short, %v required", len(data), 2) 1983 } 1984 m.Reason = Dot11Reason(binary.LittleEndian.Uint16(data[0:2])) 1985 return m.Dot11Mgmt.DecodeFromBytes(data, df) 1986} 1987 1988func (m Dot11MgmtDisassociation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 1989 buf, err := b.PrependBytes(2) 1990 1991 if err != nil { 1992 return err 1993 } 1994 1995 binary.LittleEndian.PutUint16(buf[0:2], uint16(m.Reason)) 1996 1997 return nil 1998} 1999 2000type Dot11MgmtAuthentication struct { 2001 Dot11Mgmt 2002 Algorithm Dot11Algorithm 2003 Sequence uint16 2004 Status Dot11Status 2005} 2006 2007func decodeDot11MgmtAuthentication(data []byte, p gopacket.PacketBuilder) error { 2008 d := &Dot11MgmtAuthentication{} 2009 return decodingLayerDecoder(d, data, p) 2010} 2011 2012func (m *Dot11MgmtAuthentication) LayerType() gopacket.LayerType { 2013 return LayerTypeDot11MgmtAuthentication 2014} 2015func (m *Dot11MgmtAuthentication) CanDecode() gopacket.LayerClass { 2016 return LayerTypeDot11MgmtAuthentication 2017} 2018func (m *Dot11MgmtAuthentication) NextLayerType() gopacket.LayerType { 2019 return LayerTypeDot11InformationElement 2020} 2021func (m *Dot11MgmtAuthentication) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 2022 if len(data) < 6 { 2023 df.SetTruncated() 2024 return fmt.Errorf("Dot11MgmtAuthentication length %v too short, %v required", len(data), 6) 2025 } 2026 m.Algorithm = Dot11Algorithm(binary.LittleEndian.Uint16(data[0:2])) 2027 m.Sequence = binary.LittleEndian.Uint16(data[2:4]) 2028 m.Status = Dot11Status(binary.LittleEndian.Uint16(data[4:6])) 2029 m.Payload = data[6:] 2030 return m.Dot11Mgmt.DecodeFromBytes(data, df) 2031} 2032 2033func (m Dot11MgmtAuthentication) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 2034 buf, err := b.PrependBytes(6) 2035 2036 if err != nil { 2037 return err 2038 } 2039 2040 binary.LittleEndian.PutUint16(buf[0:2], uint16(m.Algorithm)) 2041 binary.LittleEndian.PutUint16(buf[2:4], m.Sequence) 2042 binary.LittleEndian.PutUint16(buf[4:6], uint16(m.Status)) 2043 2044 return nil 2045} 2046 2047type Dot11MgmtDeauthentication struct { 2048 Dot11Mgmt 2049 Reason Dot11Reason 2050} 2051 2052func decodeDot11MgmtDeauthentication(data []byte, p gopacket.PacketBuilder) error { 2053 d := &Dot11MgmtDeauthentication{} 2054 return decodingLayerDecoder(d, data, p) 2055} 2056 2057func (m *Dot11MgmtDeauthentication) LayerType() gopacket.LayerType { 2058 return LayerTypeDot11MgmtDeauthentication 2059} 2060func (m *Dot11MgmtDeauthentication) CanDecode() gopacket.LayerClass { 2061 return LayerTypeDot11MgmtDeauthentication 2062} 2063func (m *Dot11MgmtDeauthentication) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 2064 if len(data) < 2 { 2065 df.SetTruncated() 2066 return fmt.Errorf("Dot11MgmtDeauthentication length %v too short, %v required", len(data), 2) 2067 } 2068 m.Reason = Dot11Reason(binary.LittleEndian.Uint16(data[0:2])) 2069 return m.Dot11Mgmt.DecodeFromBytes(data, df) 2070} 2071 2072func (m Dot11MgmtDeauthentication) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 2073 buf, err := b.PrependBytes(2) 2074 2075 if err != nil { 2076 return err 2077 } 2078 2079 binary.LittleEndian.PutUint16(buf[0:2], uint16(m.Reason)) 2080 2081 return nil 2082} 2083 2084type Dot11MgmtAction struct { 2085 Dot11Mgmt 2086} 2087 2088func decodeDot11MgmtAction(data []byte, p gopacket.PacketBuilder) error { 2089 d := &Dot11MgmtAction{} 2090 return decodingLayerDecoder(d, data, p) 2091} 2092 2093func (m *Dot11MgmtAction) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtAction } 2094func (m *Dot11MgmtAction) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtAction } 2095 2096type Dot11MgmtActionNoAck struct { 2097 Dot11Mgmt 2098} 2099 2100func decodeDot11MgmtActionNoAck(data []byte, p gopacket.PacketBuilder) error { 2101 d := &Dot11MgmtActionNoAck{} 2102 return decodingLayerDecoder(d, data, p) 2103} 2104 2105func (m *Dot11MgmtActionNoAck) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtActionNoAck } 2106func (m *Dot11MgmtActionNoAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtActionNoAck } 2107 2108type Dot11MgmtArubaWLAN struct { 2109 Dot11Mgmt 2110} 2111 2112func decodeDot11MgmtArubaWLAN(data []byte, p gopacket.PacketBuilder) error { 2113 d := &Dot11MgmtArubaWLAN{} 2114 return decodingLayerDecoder(d, data, p) 2115} 2116 2117func (m *Dot11MgmtArubaWLAN) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtArubaWLAN } 2118func (m *Dot11MgmtArubaWLAN) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtArubaWLAN } 2119