radiotap.go 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  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. package layers
  7. import (
  8. "bytes"
  9. "encoding/binary"
  10. "fmt"
  11. "hash/crc32"
  12. "strings"
  13. "github.com/google/gopacket"
  14. )
  15. // align calculates the number of bytes needed to align with the width
  16. // on the offset, returning the number of bytes we need to skip to
  17. // align to the offset (width).
  18. func align(offset uint16, width uint16) uint16 {
  19. return ((((offset) + ((width) - 1)) & (^((width) - 1))) - offset)
  20. }
  21. type RadioTapPresent uint32
  22. const (
  23. RadioTapPresentTSFT RadioTapPresent = 1 << iota
  24. RadioTapPresentFlags
  25. RadioTapPresentRate
  26. RadioTapPresentChannel
  27. RadioTapPresentFHSS
  28. RadioTapPresentDBMAntennaSignal
  29. RadioTapPresentDBMAntennaNoise
  30. RadioTapPresentLockQuality
  31. RadioTapPresentTxAttenuation
  32. RadioTapPresentDBTxAttenuation
  33. RadioTapPresentDBMTxPower
  34. RadioTapPresentAntenna
  35. RadioTapPresentDBAntennaSignal
  36. RadioTapPresentDBAntennaNoise
  37. RadioTapPresentRxFlags
  38. RadioTapPresentTxFlags
  39. RadioTapPresentRtsRetries
  40. RadioTapPresentDataRetries
  41. _
  42. RadioTapPresentMCS
  43. RadioTapPresentAMPDUStatus
  44. RadioTapPresentVHT
  45. RadioTapPresentEXT RadioTapPresent = 1 << 31
  46. )
  47. func (r RadioTapPresent) TSFT() bool {
  48. return r&RadioTapPresentTSFT != 0
  49. }
  50. func (r RadioTapPresent) Flags() bool {
  51. return r&RadioTapPresentFlags != 0
  52. }
  53. func (r RadioTapPresent) Rate() bool {
  54. return r&RadioTapPresentRate != 0
  55. }
  56. func (r RadioTapPresent) Channel() bool {
  57. return r&RadioTapPresentChannel != 0
  58. }
  59. func (r RadioTapPresent) FHSS() bool {
  60. return r&RadioTapPresentFHSS != 0
  61. }
  62. func (r RadioTapPresent) DBMAntennaSignal() bool {
  63. return r&RadioTapPresentDBMAntennaSignal != 0
  64. }
  65. func (r RadioTapPresent) DBMAntennaNoise() bool {
  66. return r&RadioTapPresentDBMAntennaNoise != 0
  67. }
  68. func (r RadioTapPresent) LockQuality() bool {
  69. return r&RadioTapPresentLockQuality != 0
  70. }
  71. func (r RadioTapPresent) TxAttenuation() bool {
  72. return r&RadioTapPresentTxAttenuation != 0
  73. }
  74. func (r RadioTapPresent) DBTxAttenuation() bool {
  75. return r&RadioTapPresentDBTxAttenuation != 0
  76. }
  77. func (r RadioTapPresent) DBMTxPower() bool {
  78. return r&RadioTapPresentDBMTxPower != 0
  79. }
  80. func (r RadioTapPresent) Antenna() bool {
  81. return r&RadioTapPresentAntenna != 0
  82. }
  83. func (r RadioTapPresent) DBAntennaSignal() bool {
  84. return r&RadioTapPresentDBAntennaSignal != 0
  85. }
  86. func (r RadioTapPresent) DBAntennaNoise() bool {
  87. return r&RadioTapPresentDBAntennaNoise != 0
  88. }
  89. func (r RadioTapPresent) RxFlags() bool {
  90. return r&RadioTapPresentRxFlags != 0
  91. }
  92. func (r RadioTapPresent) TxFlags() bool {
  93. return r&RadioTapPresentTxFlags != 0
  94. }
  95. func (r RadioTapPresent) RtsRetries() bool {
  96. return r&RadioTapPresentRtsRetries != 0
  97. }
  98. func (r RadioTapPresent) DataRetries() bool {
  99. return r&RadioTapPresentDataRetries != 0
  100. }
  101. func (r RadioTapPresent) MCS() bool {
  102. return r&RadioTapPresentMCS != 0
  103. }
  104. func (r RadioTapPresent) AMPDUStatus() bool {
  105. return r&RadioTapPresentAMPDUStatus != 0
  106. }
  107. func (r RadioTapPresent) VHT() bool {
  108. return r&RadioTapPresentVHT != 0
  109. }
  110. func (r RadioTapPresent) EXT() bool {
  111. return r&RadioTapPresentEXT != 0
  112. }
  113. type RadioTapChannelFlags uint16
  114. const (
  115. RadioTapChannelFlagsTurbo RadioTapChannelFlags = 0x0010 // Turbo channel
  116. RadioTapChannelFlagsCCK RadioTapChannelFlags = 0x0020 // CCK channel
  117. RadioTapChannelFlagsOFDM RadioTapChannelFlags = 0x0040 // OFDM channel
  118. RadioTapChannelFlagsGhz2 RadioTapChannelFlags = 0x0080 // 2 GHz spectrum channel.
  119. RadioTapChannelFlagsGhz5 RadioTapChannelFlags = 0x0100 // 5 GHz spectrum channel
  120. RadioTapChannelFlagsPassive RadioTapChannelFlags = 0x0200 // Only passive scan allowed
  121. RadioTapChannelFlagsDynamic RadioTapChannelFlags = 0x0400 // Dynamic CCK-OFDM channel
  122. RadioTapChannelFlagsGFSK RadioTapChannelFlags = 0x0800 // GFSK channel (FHSS PHY)
  123. )
  124. func (r RadioTapChannelFlags) Turbo() bool {
  125. return r&RadioTapChannelFlagsTurbo != 0
  126. }
  127. func (r RadioTapChannelFlags) CCK() bool {
  128. return r&RadioTapChannelFlagsCCK != 0
  129. }
  130. func (r RadioTapChannelFlags) OFDM() bool {
  131. return r&RadioTapChannelFlagsOFDM != 0
  132. }
  133. func (r RadioTapChannelFlags) Ghz2() bool {
  134. return r&RadioTapChannelFlagsGhz2 != 0
  135. }
  136. func (r RadioTapChannelFlags) Ghz5() bool {
  137. return r&RadioTapChannelFlagsGhz5 != 0
  138. }
  139. func (r RadioTapChannelFlags) Passive() bool {
  140. return r&RadioTapChannelFlagsPassive != 0
  141. }
  142. func (r RadioTapChannelFlags) Dynamic() bool {
  143. return r&RadioTapChannelFlagsDynamic != 0
  144. }
  145. func (r RadioTapChannelFlags) GFSK() bool {
  146. return r&RadioTapChannelFlagsGFSK != 0
  147. }
  148. // String provides a human readable string for RadioTapChannelFlags.
  149. // This string is possibly subject to change over time; if you're storing this
  150. // persistently, you should probably store the RadioTapChannelFlags value, not its string.
  151. func (a RadioTapChannelFlags) String() string {
  152. var out bytes.Buffer
  153. if a.Turbo() {
  154. out.WriteString("Turbo,")
  155. }
  156. if a.CCK() {
  157. out.WriteString("CCK,")
  158. }
  159. if a.OFDM() {
  160. out.WriteString("OFDM,")
  161. }
  162. if a.Ghz2() {
  163. out.WriteString("Ghz2,")
  164. }
  165. if a.Ghz5() {
  166. out.WriteString("Ghz5,")
  167. }
  168. if a.Passive() {
  169. out.WriteString("Passive,")
  170. }
  171. if a.Dynamic() {
  172. out.WriteString("Dynamic,")
  173. }
  174. if a.GFSK() {
  175. out.WriteString("GFSK,")
  176. }
  177. if length := out.Len(); length > 0 {
  178. return string(out.Bytes()[:length-1]) // strip final comma
  179. }
  180. return ""
  181. }
  182. type RadioTapFlags uint8
  183. const (
  184. RadioTapFlagsCFP RadioTapFlags = 1 << iota // sent/received during CFP
  185. RadioTapFlagsShortPreamble // sent/received * with short * preamble
  186. RadioTapFlagsWEP // sent/received * with WEP encryption
  187. RadioTapFlagsFrag // sent/received * with fragmentation
  188. RadioTapFlagsFCS // frame includes FCS
  189. RadioTapFlagsDatapad // frame has padding between * 802.11 header and payload * (to 32-bit boundary)
  190. RadioTapFlagsBadFCS // does not pass FCS check
  191. RadioTapFlagsShortGI // HT short GI
  192. )
  193. func (r RadioTapFlags) CFP() bool {
  194. return r&RadioTapFlagsCFP != 0
  195. }
  196. func (r RadioTapFlags) ShortPreamble() bool {
  197. return r&RadioTapFlagsShortPreamble != 0
  198. }
  199. func (r RadioTapFlags) WEP() bool {
  200. return r&RadioTapFlagsWEP != 0
  201. }
  202. func (r RadioTapFlags) Frag() bool {
  203. return r&RadioTapFlagsFrag != 0
  204. }
  205. func (r RadioTapFlags) FCS() bool {
  206. return r&RadioTapFlagsFCS != 0
  207. }
  208. func (r RadioTapFlags) Datapad() bool {
  209. return r&RadioTapFlagsDatapad != 0
  210. }
  211. func (r RadioTapFlags) BadFCS() bool {
  212. return r&RadioTapFlagsBadFCS != 0
  213. }
  214. func (r RadioTapFlags) ShortGI() bool {
  215. return r&RadioTapFlagsShortGI != 0
  216. }
  217. // String provides a human readable string for RadioTapFlags.
  218. // This string is possibly subject to change over time; if you're storing this
  219. // persistently, you should probably store the RadioTapFlags value, not its string.
  220. func (a RadioTapFlags) String() string {
  221. var out bytes.Buffer
  222. if a.CFP() {
  223. out.WriteString("CFP,")
  224. }
  225. if a.ShortPreamble() {
  226. out.WriteString("SHORT-PREAMBLE,")
  227. }
  228. if a.WEP() {
  229. out.WriteString("WEP,")
  230. }
  231. if a.Frag() {
  232. out.WriteString("FRAG,")
  233. }
  234. if a.FCS() {
  235. out.WriteString("FCS,")
  236. }
  237. if a.Datapad() {
  238. out.WriteString("DATAPAD,")
  239. }
  240. if a.ShortGI() {
  241. out.WriteString("SHORT-GI,")
  242. }
  243. if length := out.Len(); length > 0 {
  244. return string(out.Bytes()[:length-1]) // strip final comma
  245. }
  246. return ""
  247. }
  248. type RadioTapRate uint8
  249. func (a RadioTapRate) String() string {
  250. return fmt.Sprintf("%v Mb/s", 0.5*float32(a))
  251. }
  252. type RadioTapChannelFrequency uint16
  253. func (a RadioTapChannelFrequency) String() string {
  254. return fmt.Sprintf("%d MHz", a)
  255. }
  256. type RadioTapRxFlags uint16
  257. const (
  258. RadioTapRxFlagsBadPlcp RadioTapRxFlags = 0x0002
  259. )
  260. func (self RadioTapRxFlags) BadPlcp() bool {
  261. return self&RadioTapRxFlagsBadPlcp != 0
  262. }
  263. func (self RadioTapRxFlags) String() string {
  264. if self.BadPlcp() {
  265. return "BADPLCP"
  266. }
  267. return ""
  268. }
  269. type RadioTapTxFlags uint16
  270. const (
  271. RadioTapTxFlagsFail RadioTapTxFlags = 1 << iota
  272. RadioTapTxFlagsCTS
  273. RadioTapTxFlagsRTS
  274. RadioTapTxFlagsNoACK
  275. )
  276. func (self RadioTapTxFlags) Fail() bool { return self&RadioTapTxFlagsFail != 0 }
  277. func (self RadioTapTxFlags) CTS() bool { return self&RadioTapTxFlagsCTS != 0 }
  278. func (self RadioTapTxFlags) RTS() bool { return self&RadioTapTxFlagsRTS != 0 }
  279. func (self RadioTapTxFlags) NoACK() bool { return self&RadioTapTxFlagsNoACK != 0 }
  280. func (self RadioTapTxFlags) String() string {
  281. var tokens []string
  282. if self.Fail() {
  283. tokens = append(tokens, "Fail")
  284. }
  285. if self.CTS() {
  286. tokens = append(tokens, "CTS")
  287. }
  288. if self.RTS() {
  289. tokens = append(tokens, "RTS")
  290. }
  291. if self.NoACK() {
  292. tokens = append(tokens, "NoACK")
  293. }
  294. return strings.Join(tokens, ",")
  295. }
  296. type RadioTapMCS struct {
  297. Known RadioTapMCSKnown
  298. Flags RadioTapMCSFlags
  299. MCS uint8
  300. }
  301. func (self RadioTapMCS) String() string {
  302. var tokens []string
  303. if self.Known.Bandwidth() {
  304. token := "?"
  305. switch self.Flags.Bandwidth() {
  306. case 0:
  307. token = "20"
  308. case 1:
  309. token = "40"
  310. case 2:
  311. token = "40(20L)"
  312. case 3:
  313. token = "40(20U)"
  314. }
  315. tokens = append(tokens, token)
  316. }
  317. if self.Known.MCSIndex() {
  318. tokens = append(tokens, fmt.Sprintf("MCSIndex#%d", self.MCS))
  319. }
  320. if self.Known.GuardInterval() {
  321. if self.Flags.ShortGI() {
  322. tokens = append(tokens, fmt.Sprintf("shortGI"))
  323. } else {
  324. tokens = append(tokens, fmt.Sprintf("longGI"))
  325. }
  326. }
  327. if self.Known.HTFormat() {
  328. if self.Flags.Greenfield() {
  329. tokens = append(tokens, fmt.Sprintf("HT-greenfield"))
  330. } else {
  331. tokens = append(tokens, fmt.Sprintf("HT-mixed"))
  332. }
  333. }
  334. if self.Known.FECType() {
  335. if self.Flags.FECLDPC() {
  336. tokens = append(tokens, fmt.Sprintf("LDPC"))
  337. } else {
  338. tokens = append(tokens, fmt.Sprintf("BCC"))
  339. }
  340. }
  341. if self.Known.STBC() {
  342. tokens = append(tokens, fmt.Sprintf("STBC#%d", self.Flags.STBC()))
  343. }
  344. if self.Known.NESS() {
  345. num := 0
  346. if self.Known.NESS1() {
  347. num |= 0x02
  348. }
  349. if self.Flags.NESS0() {
  350. num |= 0x01
  351. }
  352. tokens = append(tokens, fmt.Sprintf("num-of-ESS#%d", num))
  353. }
  354. return strings.Join(tokens, ",")
  355. }
  356. type RadioTapMCSKnown uint8
  357. const (
  358. RadioTapMCSKnownBandwidth RadioTapMCSKnown = 1 << iota
  359. RadioTapMCSKnownMCSIndex
  360. RadioTapMCSKnownGuardInterval
  361. RadioTapMCSKnownHTFormat
  362. RadioTapMCSKnownFECType
  363. RadioTapMCSKnownSTBC
  364. RadioTapMCSKnownNESS
  365. RadioTapMCSKnownNESS1
  366. )
  367. func (self RadioTapMCSKnown) Bandwidth() bool { return self&RadioTapMCSKnownBandwidth != 0 }
  368. func (self RadioTapMCSKnown) MCSIndex() bool { return self&RadioTapMCSKnownMCSIndex != 0 }
  369. func (self RadioTapMCSKnown) GuardInterval() bool { return self&RadioTapMCSKnownGuardInterval != 0 }
  370. func (self RadioTapMCSKnown) HTFormat() bool { return self&RadioTapMCSKnownHTFormat != 0 }
  371. func (self RadioTapMCSKnown) FECType() bool { return self&RadioTapMCSKnownFECType != 0 }
  372. func (self RadioTapMCSKnown) STBC() bool { return self&RadioTapMCSKnownSTBC != 0 }
  373. func (self RadioTapMCSKnown) NESS() bool { return self&RadioTapMCSKnownNESS != 0 }
  374. func (self RadioTapMCSKnown) NESS1() bool { return self&RadioTapMCSKnownNESS1 != 0 }
  375. type RadioTapMCSFlags uint8
  376. const (
  377. RadioTapMCSFlagsBandwidthMask RadioTapMCSFlags = 0x03
  378. RadioTapMCSFlagsShortGI = 0x04
  379. RadioTapMCSFlagsGreenfield = 0x08
  380. RadioTapMCSFlagsFECLDPC = 0x10
  381. RadioTapMCSFlagsSTBCMask = 0x60
  382. RadioTapMCSFlagsNESS0 = 0x80
  383. )
  384. func (self RadioTapMCSFlags) Bandwidth() int {
  385. return int(self & RadioTapMCSFlagsBandwidthMask)
  386. }
  387. func (self RadioTapMCSFlags) ShortGI() bool { return self&RadioTapMCSFlagsShortGI != 0 }
  388. func (self RadioTapMCSFlags) Greenfield() bool { return self&RadioTapMCSFlagsGreenfield != 0 }
  389. func (self RadioTapMCSFlags) FECLDPC() bool { return self&RadioTapMCSFlagsFECLDPC != 0 }
  390. func (self RadioTapMCSFlags) STBC() int {
  391. return int(self&RadioTapMCSFlagsSTBCMask) >> 5
  392. }
  393. func (self RadioTapMCSFlags) NESS0() bool { return self&RadioTapMCSFlagsNESS0 != 0 }
  394. type RadioTapAMPDUStatus struct {
  395. Reference uint32
  396. Flags RadioTapAMPDUStatusFlags
  397. CRC uint8
  398. }
  399. func (self RadioTapAMPDUStatus) String() string {
  400. tokens := []string{
  401. fmt.Sprintf("ref#%x", self.Reference),
  402. }
  403. if self.Flags.ReportZerolen() && self.Flags.IsZerolen() {
  404. tokens = append(tokens, fmt.Sprintf("zero-length"))
  405. }
  406. if self.Flags.LastKnown() && self.Flags.IsLast() {
  407. tokens = append(tokens, "last")
  408. }
  409. if self.Flags.DelimCRCErr() {
  410. tokens = append(tokens, "delimiter CRC error")
  411. }
  412. if self.Flags.DelimCRCKnown() {
  413. tokens = append(tokens, fmt.Sprintf("delimiter-CRC=%02x", self.CRC))
  414. }
  415. return strings.Join(tokens, ",")
  416. }
  417. type RadioTapAMPDUStatusFlags uint16
  418. const (
  419. RadioTapAMPDUStatusFlagsReportZerolen RadioTapAMPDUStatusFlags = 1 << iota
  420. RadioTapAMPDUIsZerolen
  421. RadioTapAMPDULastKnown
  422. RadioTapAMPDUIsLast
  423. RadioTapAMPDUDelimCRCErr
  424. RadioTapAMPDUDelimCRCKnown
  425. )
  426. func (self RadioTapAMPDUStatusFlags) ReportZerolen() bool {
  427. return self&RadioTapAMPDUStatusFlagsReportZerolen != 0
  428. }
  429. func (self RadioTapAMPDUStatusFlags) IsZerolen() bool { return self&RadioTapAMPDUIsZerolen != 0 }
  430. func (self RadioTapAMPDUStatusFlags) LastKnown() bool { return self&RadioTapAMPDULastKnown != 0 }
  431. func (self RadioTapAMPDUStatusFlags) IsLast() bool { return self&RadioTapAMPDUIsLast != 0 }
  432. func (self RadioTapAMPDUStatusFlags) DelimCRCErr() bool { return self&RadioTapAMPDUDelimCRCErr != 0 }
  433. func (self RadioTapAMPDUStatusFlags) DelimCRCKnown() bool { return self&RadioTapAMPDUDelimCRCKnown != 0 }
  434. type RadioTapVHT struct {
  435. Known RadioTapVHTKnown
  436. Flags RadioTapVHTFlags
  437. Bandwidth uint8
  438. MCSNSS [4]RadioTapVHTMCSNSS
  439. Coding uint8
  440. GroupId uint8
  441. PartialAID uint16
  442. }
  443. func (self RadioTapVHT) String() string {
  444. var tokens []string
  445. if self.Known.STBC() {
  446. if self.Flags.STBC() {
  447. tokens = append(tokens, "STBC")
  448. } else {
  449. tokens = append(tokens, "no STBC")
  450. }
  451. }
  452. if self.Known.TXOPPSNotAllowed() {
  453. if self.Flags.TXOPPSNotAllowed() {
  454. tokens = append(tokens, "TXOP doze not allowed")
  455. } else {
  456. tokens = append(tokens, "TXOP doze allowed")
  457. }
  458. }
  459. if self.Known.GI() {
  460. if self.Flags.SGI() {
  461. tokens = append(tokens, "short GI")
  462. } else {
  463. tokens = append(tokens, "long GI")
  464. }
  465. }
  466. if self.Known.SGINSYMDisambiguation() {
  467. if self.Flags.SGINSYMMod() {
  468. tokens = append(tokens, "NSYM mod 10=9")
  469. } else {
  470. tokens = append(tokens, "NSYM mod 10!=9 or no short GI")
  471. }
  472. }
  473. if self.Known.LDPCExtraOFDMSymbol() {
  474. if self.Flags.LDPCExtraOFDMSymbol() {
  475. tokens = append(tokens, "LDPC extra OFDM symbols")
  476. } else {
  477. tokens = append(tokens, "no LDPC extra OFDM symbols")
  478. }
  479. }
  480. if self.Known.Beamformed() {
  481. if self.Flags.Beamformed() {
  482. tokens = append(tokens, "beamformed")
  483. } else {
  484. tokens = append(tokens, "no beamformed")
  485. }
  486. }
  487. if self.Known.Bandwidth() {
  488. token := "?"
  489. switch self.Bandwidth & 0x1f {
  490. case 0:
  491. token = "20"
  492. case 1:
  493. token = "40"
  494. case 2:
  495. token = "40(20L)"
  496. case 3:
  497. token = "40(20U)"
  498. case 4:
  499. token = "80"
  500. case 5:
  501. token = "80(40L)"
  502. case 6:
  503. token = "80(40U)"
  504. case 7:
  505. token = "80(20LL)"
  506. case 8:
  507. token = "80(20LU)"
  508. case 9:
  509. token = "80(20UL)"
  510. case 10:
  511. token = "80(20UU)"
  512. case 11:
  513. token = "160"
  514. case 12:
  515. token = "160(80L)"
  516. case 13:
  517. token = "160(80U)"
  518. case 14:
  519. token = "160(40LL)"
  520. case 15:
  521. token = "160(40LU)"
  522. case 16:
  523. token = "160(40UL)"
  524. case 17:
  525. token = "160(40UU)"
  526. case 18:
  527. token = "160(20LLL)"
  528. case 19:
  529. token = "160(20LLU)"
  530. case 20:
  531. token = "160(20LUL)"
  532. case 21:
  533. token = "160(20LUU)"
  534. case 22:
  535. token = "160(20ULL)"
  536. case 23:
  537. token = "160(20ULU)"
  538. case 24:
  539. token = "160(20UUL)"
  540. case 25:
  541. token = "160(20UUU)"
  542. }
  543. tokens = append(tokens, token)
  544. }
  545. for i, MCSNSS := range self.MCSNSS {
  546. if MCSNSS.Present() {
  547. fec := "?"
  548. switch self.Coding & (1 << uint8(i)) {
  549. case 0:
  550. fec = "BCC"
  551. case 1:
  552. fec = "LDPC"
  553. }
  554. tokens = append(tokens, fmt.Sprintf("user%d(%s,%s)", i, MCSNSS.String(), fec))
  555. }
  556. }
  557. if self.Known.GroupId() {
  558. tokens = append(tokens,
  559. fmt.Sprintf("group=%d", self.GroupId))
  560. }
  561. if self.Known.PartialAID() {
  562. tokens = append(tokens,
  563. fmt.Sprintf("partial-AID=%d", self.PartialAID))
  564. }
  565. return strings.Join(tokens, ",")
  566. }
  567. type RadioTapVHTKnown uint16
  568. const (
  569. RadioTapVHTKnownSTBC RadioTapVHTKnown = 1 << iota
  570. RadioTapVHTKnownTXOPPSNotAllowed
  571. RadioTapVHTKnownGI
  572. RadioTapVHTKnownSGINSYMDisambiguation
  573. RadioTapVHTKnownLDPCExtraOFDMSymbol
  574. RadioTapVHTKnownBeamformed
  575. RadioTapVHTKnownBandwidth
  576. RadioTapVHTKnownGroupId
  577. RadioTapVHTKnownPartialAID
  578. )
  579. func (self RadioTapVHTKnown) STBC() bool { return self&RadioTapVHTKnownSTBC != 0 }
  580. func (self RadioTapVHTKnown) TXOPPSNotAllowed() bool {
  581. return self&RadioTapVHTKnownTXOPPSNotAllowed != 0
  582. }
  583. func (self RadioTapVHTKnown) GI() bool { return self&RadioTapVHTKnownGI != 0 }
  584. func (self RadioTapVHTKnown) SGINSYMDisambiguation() bool {
  585. return self&RadioTapVHTKnownSGINSYMDisambiguation != 0
  586. }
  587. func (self RadioTapVHTKnown) LDPCExtraOFDMSymbol() bool {
  588. return self&RadioTapVHTKnownLDPCExtraOFDMSymbol != 0
  589. }
  590. func (self RadioTapVHTKnown) Beamformed() bool { return self&RadioTapVHTKnownBeamformed != 0 }
  591. func (self RadioTapVHTKnown) Bandwidth() bool { return self&RadioTapVHTKnownBandwidth != 0 }
  592. func (self RadioTapVHTKnown) GroupId() bool { return self&RadioTapVHTKnownGroupId != 0 }
  593. func (self RadioTapVHTKnown) PartialAID() bool { return self&RadioTapVHTKnownPartialAID != 0 }
  594. type RadioTapVHTFlags uint8
  595. const (
  596. RadioTapVHTFlagsSTBC RadioTapVHTFlags = 1 << iota
  597. RadioTapVHTFlagsTXOPPSNotAllowed
  598. RadioTapVHTFlagsSGI
  599. RadioTapVHTFlagsSGINSYMMod
  600. RadioTapVHTFlagsLDPCExtraOFDMSymbol
  601. RadioTapVHTFlagsBeamformed
  602. )
  603. func (self RadioTapVHTFlags) STBC() bool { return self&RadioTapVHTFlagsSTBC != 0 }
  604. func (self RadioTapVHTFlags) TXOPPSNotAllowed() bool {
  605. return self&RadioTapVHTFlagsTXOPPSNotAllowed != 0
  606. }
  607. func (self RadioTapVHTFlags) SGI() bool { return self&RadioTapVHTFlagsSGI != 0 }
  608. func (self RadioTapVHTFlags) SGINSYMMod() bool { return self&RadioTapVHTFlagsSGINSYMMod != 0 }
  609. func (self RadioTapVHTFlags) LDPCExtraOFDMSymbol() bool {
  610. return self&RadioTapVHTFlagsLDPCExtraOFDMSymbol != 0
  611. }
  612. func (self RadioTapVHTFlags) Beamformed() bool { return self&RadioTapVHTFlagsBeamformed != 0 }
  613. type RadioTapVHTMCSNSS uint8
  614. func (self RadioTapVHTMCSNSS) Present() bool {
  615. return self&0x0F != 0
  616. }
  617. func (self RadioTapVHTMCSNSS) String() string {
  618. return fmt.Sprintf("NSS#%dMCS#%d", uint32(self&0xf), uint32(self>>4))
  619. }
  620. func decodeRadioTap(data []byte, p gopacket.PacketBuilder) error {
  621. d := &RadioTap{}
  622. // TODO: Should we set LinkLayer here? And implement LinkFlow
  623. return decodingLayerDecoder(d, data, p)
  624. }
  625. type RadioTap struct {
  626. BaseLayer
  627. // Version 0. Only increases for drastic changes, introduction of compatible new fields does not count.
  628. Version uint8
  629. // Length of the whole header in bytes, including it_version, it_pad, it_len, and data fields.
  630. Length uint16
  631. // Present is a bitmap telling which fields are present. Set bit 31 (0x80000000) to extend the bitmap by another 32 bits. Additional extensions are made by setting bit 31.
  632. Present RadioTapPresent
  633. // TSFT: value in microseconds of the MAC's 64-bit 802.11 Time Synchronization Function timer when the first bit of the MPDU arrived at the MAC. For received frames, only.
  634. TSFT uint64
  635. Flags RadioTapFlags
  636. // Rate Tx/Rx data rate
  637. Rate RadioTapRate
  638. // ChannelFrequency Tx/Rx frequency in MHz, followed by flags
  639. ChannelFrequency RadioTapChannelFrequency
  640. ChannelFlags RadioTapChannelFlags
  641. // FHSS For frequency-hopping radios, the hop set (first byte) and pattern (second byte).
  642. FHSS uint16
  643. // DBMAntennaSignal RF signal power at the antenna, decibel difference from one milliwatt.
  644. DBMAntennaSignal int8
  645. // DBMAntennaNoise RF noise power at the antenna, decibel difference from one milliwatt.
  646. DBMAntennaNoise int8
  647. // LockQuality Quality of Barker code lock. Unitless. Monotonically nondecreasing with "better" lock strength. Called "Signal Quality" in datasheets.
  648. LockQuality uint16
  649. // TxAttenuation Transmit power expressed as unitless distance from max power set at factory calibration. 0 is max power. Monotonically nondecreasing with lower power levels.
  650. TxAttenuation uint16
  651. // DBTxAttenuation Transmit power expressed as decibel distance from max power set at factory calibration. 0 is max power. Monotonically nondecreasing with lower power levels.
  652. DBTxAttenuation uint16
  653. // DBMTxPower Transmit power expressed as dBm (decibels from a 1 milliwatt reference). This is the absolute power level measured at the antenna port.
  654. DBMTxPower int8
  655. // Antenna Unitless indication of the Rx/Tx antenna for this packet. The first antenna is antenna 0.
  656. Antenna uint8
  657. // DBAntennaSignal RF signal power at the antenna, decibel difference from an arbitrary, fixed reference.
  658. DBAntennaSignal uint8
  659. // DBAntennaNoise RF noise power at the antenna, decibel difference from an arbitrary, fixed reference point.
  660. DBAntennaNoise uint8
  661. //
  662. RxFlags RadioTapRxFlags
  663. TxFlags RadioTapTxFlags
  664. RtsRetries uint8
  665. DataRetries uint8
  666. MCS RadioTapMCS
  667. AMPDUStatus RadioTapAMPDUStatus
  668. VHT RadioTapVHT
  669. }
  670. func (m *RadioTap) LayerType() gopacket.LayerType { return LayerTypeRadioTap }
  671. func (m *RadioTap) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  672. m.Version = uint8(data[0])
  673. m.Length = binary.LittleEndian.Uint16(data[2:4])
  674. m.Present = RadioTapPresent(binary.LittleEndian.Uint32(data[4:8]))
  675. offset := uint16(4)
  676. for (binary.LittleEndian.Uint32(data[offset:offset+4]) & 0x80000000) != 0 {
  677. // This parser only handles standard radiotap namespace,
  678. // and expects all fields are packed in the first it_present.
  679. // Extended bitmap will be just ignored.
  680. offset += 4
  681. }
  682. offset += 4 // skip the bitmap
  683. if m.Present.TSFT() {
  684. offset += align(offset, 8)
  685. m.TSFT = binary.LittleEndian.Uint64(data[offset : offset+8])
  686. offset += 8
  687. }
  688. if m.Present.Flags() {
  689. m.Flags = RadioTapFlags(data[offset])
  690. offset++
  691. }
  692. if m.Present.Rate() {
  693. m.Rate = RadioTapRate(data[offset])
  694. offset++
  695. }
  696. if m.Present.Channel() {
  697. offset += align(offset, 2)
  698. m.ChannelFrequency = RadioTapChannelFrequency(binary.LittleEndian.Uint16(data[offset : offset+2]))
  699. offset += 2
  700. m.ChannelFlags = RadioTapChannelFlags(binary.LittleEndian.Uint16(data[offset : offset+2]))
  701. offset += 2
  702. }
  703. if m.Present.FHSS() {
  704. m.FHSS = binary.LittleEndian.Uint16(data[offset : offset+2])
  705. offset += 2
  706. }
  707. if m.Present.DBMAntennaSignal() {
  708. m.DBMAntennaSignal = int8(data[offset])
  709. offset++
  710. }
  711. if m.Present.DBMAntennaNoise() {
  712. m.DBMAntennaNoise = int8(data[offset])
  713. offset++
  714. }
  715. if m.Present.LockQuality() {
  716. offset += align(offset, 2)
  717. m.LockQuality = binary.LittleEndian.Uint16(data[offset : offset+2])
  718. offset += 2
  719. }
  720. if m.Present.TxAttenuation() {
  721. offset += align(offset, 2)
  722. m.TxAttenuation = binary.LittleEndian.Uint16(data[offset : offset+2])
  723. offset += 2
  724. }
  725. if m.Present.DBTxAttenuation() {
  726. offset += align(offset, 2)
  727. m.DBTxAttenuation = binary.LittleEndian.Uint16(data[offset : offset+2])
  728. offset += 2
  729. }
  730. if m.Present.DBMTxPower() {
  731. m.DBMTxPower = int8(data[offset])
  732. offset++
  733. }
  734. if m.Present.Antenna() {
  735. m.Antenna = uint8(data[offset])
  736. offset++
  737. }
  738. if m.Present.DBAntennaSignal() {
  739. m.DBAntennaSignal = uint8(data[offset])
  740. offset++
  741. }
  742. if m.Present.DBAntennaNoise() {
  743. m.DBAntennaNoise = uint8(data[offset])
  744. offset++
  745. }
  746. if m.Present.RxFlags() {
  747. offset += align(offset, 2)
  748. m.RxFlags = RadioTapRxFlags(binary.LittleEndian.Uint16(data[offset:]))
  749. offset += 2
  750. }
  751. if m.Present.TxFlags() {
  752. offset += align(offset, 2)
  753. m.TxFlags = RadioTapTxFlags(binary.LittleEndian.Uint16(data[offset:]))
  754. offset += 2
  755. }
  756. if m.Present.RtsRetries() {
  757. m.RtsRetries = uint8(data[offset])
  758. offset++
  759. }
  760. if m.Present.DataRetries() {
  761. m.DataRetries = uint8(data[offset])
  762. offset++
  763. }
  764. if m.Present.MCS() {
  765. m.MCS = RadioTapMCS{
  766. RadioTapMCSKnown(data[offset]),
  767. RadioTapMCSFlags(data[offset+1]),
  768. uint8(data[offset+2]),
  769. }
  770. offset += 3
  771. }
  772. if m.Present.AMPDUStatus() {
  773. offset += align(offset, 4)
  774. m.AMPDUStatus = RadioTapAMPDUStatus{
  775. Reference: binary.LittleEndian.Uint32(data[offset:]),
  776. Flags: RadioTapAMPDUStatusFlags(binary.LittleEndian.Uint16(data[offset+4:])),
  777. CRC: uint8(data[offset+6]),
  778. }
  779. offset += 8
  780. }
  781. if m.Present.VHT() {
  782. offset += align(offset, 2)
  783. m.VHT = RadioTapVHT{
  784. Known: RadioTapVHTKnown(binary.LittleEndian.Uint16(data[offset:])),
  785. Flags: RadioTapVHTFlags(data[offset+2]),
  786. Bandwidth: uint8(data[offset+3]),
  787. MCSNSS: [4]RadioTapVHTMCSNSS{
  788. RadioTapVHTMCSNSS(data[offset+4]),
  789. RadioTapVHTMCSNSS(data[offset+5]),
  790. RadioTapVHTMCSNSS(data[offset+6]),
  791. RadioTapVHTMCSNSS(data[offset+7]),
  792. },
  793. Coding: uint8(data[offset+8]),
  794. GroupId: uint8(data[offset+9]),
  795. PartialAID: binary.LittleEndian.Uint16(data[offset+10:]),
  796. }
  797. offset += 12
  798. }
  799. payload := data[m.Length:]
  800. // Remove non standard padding used by some Wi-Fi drivers
  801. if m.Flags.Datapad() &&
  802. payload[0]&0xC == 0x8 { //&& // Data frame
  803. headlen := 24
  804. if payload[0]&0x8C == 0x88 { // QoS
  805. headlen += 2
  806. }
  807. if payload[1]&0x3 == 0x3 { // 4 addresses
  808. headlen += 2
  809. }
  810. if headlen%4 == 2 {
  811. payload = append(payload[:headlen], payload[headlen+2:len(payload)]...)
  812. }
  813. }
  814. if !m.Flags.FCS() {
  815. // Dot11.DecodeFromBytes() expects FCS present and performs a hard chop on the checksum
  816. // If a user is handing in subslices or packets from a buffered stream, the capacity of the slice
  817. // may extend beyond the len, rather than expecting callers to enforce cap==len on every packet
  818. // we take the hit in this one case and do a reallocation. If the user DOES enforce cap==len
  819. // then the reallocation will happen anyway on the append. This is requried because the append
  820. // write to the memory directly after the payload if there is sufficient capacity, which callers
  821. // may not expect.
  822. reallocPayload := make([]byte, len(payload)+4)
  823. copy(reallocPayload[0:len(payload)], payload)
  824. h := crc32.NewIEEE()
  825. h.Write(payload)
  826. binary.LittleEndian.PutUint32(reallocPayload[len(payload):], h.Sum32())
  827. payload = reallocPayload
  828. }
  829. m.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: payload}
  830. return nil
  831. }
  832. func (m RadioTap) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  833. buf := make([]byte, 1024)
  834. buf[0] = m.Version
  835. buf[1] = 0
  836. binary.LittleEndian.PutUint32(buf[4:8], uint32(m.Present))
  837. offset := uint16(4)
  838. for (binary.LittleEndian.Uint32(buf[offset:offset+4]) & 0x80000000) != 0 {
  839. offset += 4
  840. }
  841. offset += 4
  842. if m.Present.TSFT() {
  843. offset += align(offset, 8)
  844. binary.LittleEndian.PutUint64(buf[offset:offset+8], m.TSFT)
  845. offset += 8
  846. }
  847. if m.Present.Flags() {
  848. buf[offset] = uint8(m.Flags)
  849. offset++
  850. }
  851. if m.Present.Rate() {
  852. buf[offset] = uint8(m.Rate)
  853. offset++
  854. }
  855. if m.Present.Channel() {
  856. offset += align(offset, 2)
  857. binary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.ChannelFrequency))
  858. offset += 2
  859. binary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.ChannelFlags))
  860. offset += 2
  861. }
  862. if m.Present.FHSS() {
  863. binary.LittleEndian.PutUint16(buf[offset:offset+2], m.FHSS)
  864. offset += 2
  865. }
  866. if m.Present.DBMAntennaSignal() {
  867. buf[offset] = byte(m.DBMAntennaSignal)
  868. offset++
  869. }
  870. if m.Present.DBMAntennaNoise() {
  871. buf[offset] = byte(m.DBMAntennaNoise)
  872. offset++
  873. }
  874. if m.Present.LockQuality() {
  875. offset += align(offset, 2)
  876. binary.LittleEndian.PutUint16(buf[offset:offset+2], m.LockQuality)
  877. offset += 2
  878. }
  879. if m.Present.TxAttenuation() {
  880. offset += align(offset, 2)
  881. binary.LittleEndian.PutUint16(buf[offset:offset+2], m.TxAttenuation)
  882. offset += 2
  883. }
  884. if m.Present.DBTxAttenuation() {
  885. offset += align(offset, 2)
  886. binary.LittleEndian.PutUint16(buf[offset:offset+2], m.DBTxAttenuation)
  887. offset += 2
  888. }
  889. if m.Present.DBMTxPower() {
  890. buf[offset] = byte(m.DBMTxPower)
  891. offset++
  892. }
  893. if m.Present.Antenna() {
  894. buf[offset] = uint8(m.Antenna)
  895. offset++
  896. }
  897. if m.Present.DBAntennaSignal() {
  898. buf[offset] = uint8(m.DBAntennaSignal)
  899. offset++
  900. }
  901. if m.Present.DBAntennaNoise() {
  902. buf[offset] = uint8(m.DBAntennaNoise)
  903. offset++
  904. }
  905. if m.Present.RxFlags() {
  906. offset += align(offset, 2)
  907. binary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.RxFlags))
  908. offset += 2
  909. }
  910. if m.Present.TxFlags() {
  911. offset += align(offset, 2)
  912. binary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.TxFlags))
  913. offset += 2
  914. }
  915. if m.Present.RtsRetries() {
  916. buf[offset] = m.RtsRetries
  917. offset++
  918. }
  919. if m.Present.DataRetries() {
  920. buf[offset] = m.DataRetries
  921. offset++
  922. }
  923. if m.Present.MCS() {
  924. buf[offset] = uint8(m.MCS.Known)
  925. buf[offset+1] = uint8(m.MCS.Flags)
  926. buf[offset+2] = uint8(m.MCS.MCS)
  927. offset += 3
  928. }
  929. if m.Present.AMPDUStatus() {
  930. offset += align(offset, 4)
  931. binary.LittleEndian.PutUint32(buf[offset:offset+4], m.AMPDUStatus.Reference)
  932. binary.LittleEndian.PutUint16(buf[offset+4:offset+6], uint16(m.AMPDUStatus.Flags))
  933. buf[offset+6] = m.AMPDUStatus.CRC
  934. offset += 8
  935. }
  936. if m.Present.VHT() {
  937. offset += align(offset, 2)
  938. binary.LittleEndian.PutUint16(buf[offset:], uint16(m.VHT.Known))
  939. buf[offset+2] = uint8(m.VHT.Flags)
  940. buf[offset+3] = uint8(m.VHT.Bandwidth)
  941. buf[offset+4] = uint8(m.VHT.MCSNSS[0])
  942. buf[offset+5] = uint8(m.VHT.MCSNSS[1])
  943. buf[offset+6] = uint8(m.VHT.MCSNSS[2])
  944. buf[offset+7] = uint8(m.VHT.MCSNSS[3])
  945. buf[offset+8] = uint8(m.VHT.Coding)
  946. buf[offset+9] = uint8(m.VHT.GroupId)
  947. binary.LittleEndian.PutUint16(buf[offset+10:offset+12], m.VHT.PartialAID)
  948. offset += 12
  949. }
  950. packetBuf, err := b.PrependBytes(int(offset))
  951. if err != nil {
  952. return err
  953. }
  954. if opts.FixLengths {
  955. m.Length = offset
  956. }
  957. binary.LittleEndian.PutUint16(buf[2:4], m.Length)
  958. copy(packetBuf, buf)
  959. return nil
  960. }
  961. func (m *RadioTap) CanDecode() gopacket.LayerClass { return LayerTypeRadioTap }
  962. func (m *RadioTap) NextLayerType() gopacket.LayerType { return LayerTypeDot11 }