radiotap.go 30 KB

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