package main import ( "bufio" "bytes" "encoding/csv" "fmt" "io/ioutil" "log" "os" "path/filepath" "strconv" "strings" "time" ) type WifiClient struct { MACAdress string FirstSeen time.Time LastSeen time.Time Power int64 Packets int64 } const CSVDumps = `/home/konrad/go/src/git.kolaente.de/konrad/wifi-statistics` const TheClientCSVHeader = `Station MAC, First time seen, Last time seen, Power, # packets, BSSID, Probed ESSIDs` const SecondsUntilInactive = 120 func main() { clients := ParseCSVDump(CSVDumps) var activeClients int64 for _, c := range clients { fmt.Println(fmt.Sprintf("Mac: %s | First seen: %s | Last seen: %s | Power: %d | Packets: %d | Active: %t", c.MACAdress, c.FirstSeen.String(), c.LastSeen.String(), c.Power, c.Packets, c.isActive())) if c.isActive() { activeClients++ } } fmt.Println("Active Clients:", activeClients) fmt.Println("Total Clients:", len(clients)) } func ParseCSVDump(pathToDumps string) (clients []*WifiClient) { err := filepath.Walk(pathToDumps, func(dumpPath string, info os.FileInfo, err error) error { if err != nil { return err } // Only csv files if info.IsDir() || filepath.Ext(dumpPath) != ".csv" { return nil } bs, err := ioutil.ReadFile(dumpPath) if err != nil { log.Fatal(err) } all := string(bs) i := 0 i = strings.Index(all, TheClientCSVHeader) arefun := all[i+len(TheClientCSVHeader)+1:] arefun = strings.Replace(arefun, " ", "", -1) scanner := bufio.NewScanner(strings.NewReader(arefun)) for scanner.Scan() { r := csv.NewReader(bytes.NewReader(scanner.Bytes())) record, err := r.Read() if err != nil { if err.Error() == "EOF" { continue } log.Fatal(err) } power, err := strconv.ParseInt(record[3], 10, 64) if err != nil { log.Fatal(err) } packets, err := strconv.ParseInt(record[4], 10, 64) if err != nil { log.Fatal(err) } clients = append(clients, &WifiClient{ MACAdress: record[0], FirstSeen: parseDateToUnix(record[1]), LastSeen: parseDateToUnix(record[2]), Power: power, Packets: packets, }) } return nil }) if err != nil { log.Fatal(err) } return } func parseDateToUnix(date string) (unix time.Time) { unix, err := time.Parse("2006-01-0215:04:05", date) if err != nil { log.Fatal(err) } return } func (c *WifiClient) isActive() bool { // Should normally not be set here, should take the system time -> see below current := time.Date(2018, 11, 14, 14, 31, 0, 0, &time.Location{}) diff := current.Sub(c.LastSeen) //diff := time.Since(c.LastSeen) if diff < SecondsUntilInactive*time.Second { return true } return false }