-
Notifications
You must be signed in to change notification settings - Fork 2
/
extraction.go
136 lines (110 loc) · 2.74 KB
/
extraction.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"github.com/golang/glog"
"googlemaps.github.io/maps"
)
type informMsg struct {
Type string `json:"_type"`
MgmtCfg string `json:"mgmt_cfg"`
AuthKey string
RadioTable []Radio `json:"radio_table"`
Location Geo
Serial string `json:"serial"`
}
type Geo struct {
}
type Radio struct {
ScanTable []Neighbor `json:"scan_table"`
}
type Neighbor struct {
Band string `json:"band"`
BSSID string `json:"bssid"`
Bandwidth int `json:"bw"`
Channel int `json:"channel"`
ESSID string `json:"essid"`
Noise int `json:"noise"`
Signal int `json:"signal"`
Age int `json:"age"`
}
var located SafeUniqueList
func extractInfo(payload []byte, src string) {
var im informMsg
payload = []byte(strings.ReplaceAll(string(payload), "\\n", ","))
json.Unmarshal(payload, &im)
if im.Type == "setparam" {
chunks := strings.Split(im.MgmtCfg, ",")
for _, c := range chunks {
parts := strings.Split(c, "=")
if len(parts) != 2 {
continue
}
if parts[0] == "authkey" {
im.AuthKey = parts[1]
sk.AddKey(im.AuthKey)
glog.Infof("discovered key: %s for %s\n", im.AuthKey, src)
break
}
}
}
if showCoords == true && im.RadioTable != nil {
updateGeo(im)
}
}
func updateGeo(im informMsg) {
// check if we've already dumped geo info for device
if located.Exists(im.Serial) {
return
}
pdKey := os.Getenv("PD_MAPS_API_KEY")
if pdKey == "" {
glog.Info("not geolocating because no API Key, set google maps key in env PD_MAPS_API_KEY")
return
}
neighbors := flattenNeighbors(im.RadioTable)
waps := neighborsToWAP(neighbors)
gRec := maps.GeolocationRequest{
ConsiderIP: false,
WiFiAccessPoints: waps,
}
mc, err := maps.NewClient(maps.WithAPIKey(pdKey))
if err != nil {
glog.Errorf("could not init maps client: %s", err)
return
}
gr, err := mc.Geolocate(context.Background(), &gRec)
if err != nil {
glog.Errorf("could not geolocation device %s: %s", im.Serial, err)
return
}
fmt.Printf("Device %s at %f,%f (%f)\n", im.Serial, gr.Location.Lat, gr.Location.Lng, gr.Accuracy)
return
}
func neighborsToWAP(neighbors []Neighbor) []maps.WiFiAccessPoint {
waps := []maps.WiFiAccessPoint{}
for _, n := range neighbors {
if n.Signal == 0 {
continue
}
snr := n.Signal - n.Noise
wap := maps.WiFiAccessPoint{
MACAddress: n.BSSID,
SignalStrength: float64(n.Signal),
Channel: n.Channel,
SignalToNoiseRatio: float64(snr),
}
waps = append(waps, wap)
}
return waps
}
func flattenNeighbors(radios []Radio) []Neighbor {
neighbors := []Neighbor{}
for _, radio := range radios {
neighbors = append(neighbors, radio.ScanTable...)
}
return neighbors
}