dot11_wps.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package packets
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "encoding/hex"
  6. "fmt"
  7. "net"
  8. "github.com/google/gopacket"
  9. "github.com/google/gopacket/layers"
  10. )
  11. var (
  12. wpsSignatureBytes = []byte{0x00, 0x50, 0xf2, 0x04}
  13. )
  14. func wpsUint16At(data []byte, size int, offset *int) (bool, uint16) {
  15. if *offset <= size-2 {
  16. off := *offset
  17. *offset += 2
  18. return true, binary.BigEndian.Uint16(data[off:])
  19. }
  20. // fmt.Printf("uint16At( data(%d), off=%d )\n", size, *offset)
  21. return false, 0
  22. }
  23. func wpsDataAt(data []byte, size int, offset *int, num int) (bool, []byte) {
  24. max := size - num
  25. if *offset <= max {
  26. off := *offset
  27. *offset += num
  28. return true, data[off : off+num]
  29. }
  30. // fmt.Printf("dataAt( data(%d), off=%d, num=%d )\n", size, *offset, num)
  31. return false, nil
  32. }
  33. func dot11ParseWPSTag(id uint16, size uint16, data []byte, info *map[string]string) {
  34. name := ""
  35. val := ""
  36. if attr, found := wpsAttributes[id]; found {
  37. name = attr.Name
  38. if attr.Type == wpsStr {
  39. val = string(data)
  40. } else {
  41. val = hex.EncodeToString(data)
  42. }
  43. if attr.Desc != nil {
  44. if desc, found := attr.Desc[val]; found {
  45. val = desc
  46. }
  47. }
  48. if attr.Func != nil {
  49. val = attr.Func(data, info)
  50. }
  51. } else {
  52. name = fmt.Sprintf("0x%X", id)
  53. val = hex.EncodeToString(data)
  54. }
  55. if val != "" {
  56. (*info)[name] = val
  57. }
  58. }
  59. func dot11ParseWPSData(data []byte) (ok bool, info map[string]string) {
  60. info = map[string]string{}
  61. size := len(data)
  62. for offset := 0; offset < size; {
  63. ok := false
  64. tagId := uint16(0)
  65. tagLen := uint16(0)
  66. tagData := []byte(nil)
  67. if ok, tagId = wpsUint16At(data, size, &offset); !ok {
  68. break
  69. } else if ok, tagLen = wpsUint16At(data, size, &offset); !ok {
  70. break
  71. } else if ok, tagData = wpsDataAt(data, size, &offset, int(tagLen)); !ok {
  72. break
  73. } else {
  74. dot11ParseWPSTag(tagId, tagLen, tagData, &info)
  75. }
  76. }
  77. return true, info
  78. }
  79. func Dot11ParseWPS(packet gopacket.Packet, dot11 *layers.Dot11) (ok bool, bssid net.HardwareAddr, info map[string]string) {
  80. ok = false
  81. for _, layer := range packet.Layers() {
  82. if layer.LayerType() == layers.LayerTypeDot11InformationElement {
  83. if dot11info, infoOk := layer.(*layers.Dot11InformationElement); infoOk && dot11info.ID == layers.Dot11InformationElementIDVendor {
  84. if bytes.Equal(dot11info.OUI, wpsSignatureBytes) {
  85. bssid = dot11.Address3
  86. ok, info = dot11ParseWPSData(dot11info.Info)
  87. return
  88. }
  89. }
  90. }
  91. }
  92. return
  93. }