Initial commit: WLC 9800 client management tool with AP and SSID filtering

This commit is contained in:
2025-11-13 02:44:47 +07:00
commit 2369fc779c
7 changed files with 1179 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
get-android
clients.db
*.db

70
README.md Normal file
View File

@@ -0,0 +1,70 @@
# WLC 9800 Tools
Tools for managing Cisco WLC 9800 wireless clients.
## get-android
A tool to fetch and store wireless client data from Cisco WLC 9800.
### Features
- Fetch all wireless clients from Cisco WLC 9800
- Filter Android devices by manufacturer OUI
- Store client data in SQLite database
- Display stored clients with filtering options
- Filter by AP name and SSID
### Build
```bash
go build -o get-android
```
### Usage
Fetch all clients and store in database:
```bash
./get-android
```
Fetch only Android devices (filtered by OUI):
```bash
./get-android --oui
```
Show all stored clients:
```bash
./get-android --show
```
Show only Android devices:
```bash
./get-android --show --android
```
Filter by AP name:
```bash
./get-android --show --ap "Medan"
```
Filter by SSID:
```bash
./get-android --show --ssid "#IOHGuest"
```
Combine filters:
```bash
./get-android --show --ssid "#IOHGuest" --ap "Medan" --android
```
### Database Schema
The tool stores client data in `clients.db` with the following fields:
- client_mac
- ap_name
- ssid
- device_type
- day_zero_dc
- device_name
- device_vendor
- timestamp

BIN
block-android Executable file

Binary file not shown.

5
go.mod Normal file
View File

@@ -0,0 +1,5 @@
module block-android
go 1.21
require github.com/mattn/go-sqlite3 v1.14.18

2
go.sum Normal file
View File

@@ -0,0 +1,2 @@
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=

383
main.go Normal file
View File

@@ -0,0 +1,383 @@
package main
import (
"crypto/tls"
"database/sql"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net/http"
"strings"
"time"
_ "github.com/mattn/go-sqlite3"
)
type ClientOperData struct {
CiscoIOSXEWirelessClientOper struct {
CommonOperData []struct {
ClientMac string `json:"client-mac"`
ApName string `json:"ap-name"`
WlanID int `json:"wlan-id"`
} `json:"common-oper-data"`
Dot11OperData []struct {
ClientMac string `json:"ms-mac-address"`
VapSSID string `json:"vap-ssid"`
} `json:"dot11-oper-data"`
DCInfo []struct {
ClientMac string `json:"client-mac"`
DeviceType string `json:"device-type"`
DayZeroDC string `json:"day-zero-dc"`
DeviceName string `json:"device-name"`
DeviceVendor string `json:"device-vendor"`
} `json:"dc-info"`
} `json:"Cisco-IOS-XE-wireless-client-oper:client-oper-data"`
}
func isAndroidDevice(mac string) (bool, string) {
macUpper := strings.ToUpper(mac)
parts := strings.Split(macUpper, ":")
if len(parts) < 3 {
return false, ""
}
oui := strings.Join(parts[:3], ":")
if manufacturer, exists := androidManufacturerOUIs[strings.ToLower(oui)]; exists {
return true, manufacturer
}
return false, ""
}
func main() {
showFlag := flag.Bool("show", false, "Show stored clients")
androidOnlyFlag := flag.Bool("android", false, "Show only Android devices (use with -show)")
ouiFilterFlag := flag.Bool("oui", false, "Filter by Android manufacturer OUI when fetching")
apFilterFlag := flag.String("ap", "", "Filter by AP name (use with -show)")
ssidFilterFlag := flag.String("ssid", "", "Filter by SSID (use with -show)")
flag.Parse()
db, err := initDB()
if err != nil {
log.Fatal("Failed to initialize database:", err)
}
defer db.Close()
if *showFlag {
if err := showClients(db, *androidOnlyFlag, *apFilterFlag, *ssidFilterFlag); err != nil {
log.Fatal("Failed to show clients:", err)
}
return
}
data, err := fetchClientData()
if err != nil {
log.Fatal("Failed to fetch client data:", err)
}
var clientsToSave []map[string]string
if *ouiFilterFlag {
clientsToSave = filterByOUI(data)
fmt.Printf("Filtered %d Android devices by OUI\n", len(clientsToSave))
} else {
clientsToSave = getAllClients(data)
}
if err := saveToDatabase(db, clientsToSave); err != nil {
log.Fatal("Failed to save to database:", err)
}
fmt.Printf("Successfully saved %d clients to database\n", len(clientsToSave))
}
func initDB() (*sql.DB, error) {
db, err := sql.Open("sqlite3", "./clients.db")
if err != nil {
return nil, err
}
createTableSQL := `CREATE TABLE IF NOT EXISTS android_clients (
id INTEGER PRIMARY KEY AUTOINCREMENT,
client_mac TEXT NOT NULL,
ap_name TEXT,
ssid TEXT,
device_type TEXT,
day_zero_dc TEXT,
device_name TEXT,
device_vendor TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);`
_, err = db.Exec(createTableSQL)
if err != nil {
return nil, err
}
return db, nil
}
func fetchClientData() (*ClientOperData, error) {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{
Transport: tr,
Timeout: 60 * time.Second,
}
req, err := http.NewRequest("GET", "https://10.0.3.4/restconf/data/Cisco-IOS-XE-wireless-client-oper:client-oper-data", nil)
if err != nil {
return nil, err
}
req.SetBasicAuth("othman.suseno", "Pnd77net!")
req.Header.Set("Accept", "application/yang-data+json")
fmt.Println("Fetching data from Cisco API...")
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API returned status code: %d", resp.StatusCode)
}
fmt.Println("Reading response...")
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
fmt.Printf("Received %d bytes, parsing JSON...\n", len(body))
var data ClientOperData
if err := json.Unmarshal(body, &data); err != nil {
return nil, fmt.Errorf("failed to parse JSON: %w", err)
}
return &data, nil
}
func getAllClients(data *ClientOperData) []map[string]string {
var allClients []map[string]string
dcInfoMap := make(map[string]map[string]string)
for _, dc := range data.CiscoIOSXEWirelessClientOper.DCInfo {
dcInfoMap[dc.ClientMac] = map[string]string{
"device_type": dc.DeviceType,
"day_zero_dc": dc.DayZeroDC,
"device_name": dc.DeviceName,
"device_vendor": dc.DeviceVendor,
}
}
dot11InfoMap := make(map[string]string)
for _, dot11 := range data.CiscoIOSXEWirelessClientOper.Dot11OperData {
dot11InfoMap[dot11.ClientMac] = dot11.VapSSID
}
fmt.Printf("Found %d clients with device classification info\n", len(dcInfoMap))
fmt.Printf("Found %d clients with SSID info\n", len(dot11InfoMap))
fmt.Printf("Found %d total clients in common-oper-data\n", len(data.CiscoIOSXEWirelessClientOper.CommonOperData))
for i, client := range data.CiscoIOSXEWirelessClientOper.CommonOperData {
dcInfo, hasDCInfo := dcInfoMap[client.ClientMac]
ssid, hasSSID := dot11InfoMap[client.ClientMac]
if i < 3 {
fmt.Printf("Sample client %d: MAC=%s, AP=%s, SSID=%s\n",
i+1, client.ClientMac, client.ApName, ssid)
}
clientData := map[string]string{
"client_mac": client.ClientMac,
"ap_name": client.ApName,
"ssid": "",
"device_type": "",
"day_zero_dc": "",
"device_name": "",
"device_vendor": "",
}
if hasSSID {
clientData["ssid"] = ssid
}
if hasDCInfo {
clientData["device_type"] = dcInfo["device_type"]
clientData["day_zero_dc"] = dcInfo["day_zero_dc"]
clientData["device_name"] = dcInfo["device_name"]
clientData["device_vendor"] = dcInfo["device_vendor"]
}
allClients = append(allClients, clientData)
}
return allClients
}
func filterByOUI(data *ClientOperData) []map[string]string {
var androidClients []map[string]string
dcInfoMap := make(map[string]map[string]string)
for _, dc := range data.CiscoIOSXEWirelessClientOper.DCInfo {
dcInfoMap[dc.ClientMac] = map[string]string{
"device_type": dc.DeviceType,
"day_zero_dc": dc.DayZeroDC,
"device_name": dc.DeviceName,
"device_vendor": dc.DeviceVendor,
}
}
dot11InfoMap := make(map[string]string)
for _, dot11 := range data.CiscoIOSXEWirelessClientOper.Dot11OperData {
dot11InfoMap[dot11.ClientMac] = dot11.VapSSID
}
androidCount := 0
for _, client := range data.CiscoIOSXEWirelessClientOper.CommonOperData {
isAndroid, manufacturer := isAndroidDevice(client.ClientMac)
if isAndroid {
dcInfo, hasDCInfo := dcInfoMap[client.ClientMac]
ssid, hasSSID := dot11InfoMap[client.ClientMac]
clientData := map[string]string{
"client_mac": client.ClientMac,
"ap_name": client.ApName,
"ssid": "",
"device_type": "",
"day_zero_dc": "",
"device_name": "",
"device_vendor": manufacturer,
}
if hasSSID {
clientData["ssid"] = ssid
}
if hasDCInfo {
clientData["device_type"] = dcInfo["device_type"]
clientData["day_zero_dc"] = dcInfo["day_zero_dc"]
clientData["device_name"] = dcInfo["device_name"]
if dcInfo["device_vendor"] != "" {
clientData["device_vendor"] = dcInfo["device_vendor"]
}
}
androidClients = append(androidClients, clientData)
androidCount++
if androidCount <= 5 {
fmt.Printf("Found Android device: MAC=%s, AP=%s, SSID=%s, Manufacturer=%s\n",
client.ClientMac, client.ApName, clientData["ssid"], manufacturer)
}
}
}
return androidClients
}
func saveToDatabase(db *sql.DB, clients []map[string]string) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
stmt, err := tx.Prepare(`INSERT INTO android_clients
(client_mac, ap_name, ssid, device_type, day_zero_dc, device_name, device_vendor)
VALUES (?, ?, ?, ?, ?, ?, ?)`)
if err != nil {
return err
}
defer stmt.Close()
for _, client := range clients {
_, err = stmt.Exec(
client["client_mac"],
client["ap_name"],
client["ssid"],
client["device_type"],
client["day_zero_dc"],
client["device_name"],
client["device_vendor"],
)
if err != nil {
return err
}
}
return tx.Commit()
}
func showClients(db *sql.DB, androidOnly bool, apFilter string, ssidFilter string) error {
query := "SELECT client_mac, ap_name, ssid, device_type, day_zero_dc, device_name, device_vendor FROM android_clients"
var args []interface{}
var conditions []string
if apFilter != "" {
conditions = append(conditions, "ap_name LIKE ?")
args = append(args, "%"+apFilter+"%")
}
if ssidFilter != "" {
conditions = append(conditions, "ssid LIKE ?")
args = append(args, "%"+ssidFilter+"%")
}
if len(conditions) > 0 {
query += " WHERE " + strings.Join(conditions, " AND ")
}
rows, err := db.Query(query, args...)
if err != nil {
return err
}
defer rows.Close()
fmt.Println("\n=== Stored Clients ===")
fmt.Printf("%-20s %-20s %-20s %-15s %-15s %-30s %-20s\n",
"MAC Address", "AP Name", "SSID", "Device Type", "Day Zero DC", "Device Name", "Device Vendor")
fmt.Println(strings.Repeat("-", 140))
count := 0
androidCount := 0
for rows.Next() {
var mac, apName, ssid, deviceType, dayZeroDC, deviceName, deviceVendor string
if err := rows.Scan(&mac, &apName, &ssid, &deviceType, &dayZeroDC, &deviceName, &deviceVendor); err != nil {
return err
}
isAndroid, manufacturer := isAndroidDevice(mac)
if androidOnly && !isAndroid {
continue
}
if isAndroid {
androidCount++
if deviceVendor == "" {
deviceVendor = manufacturer
}
}
fmt.Printf("%-20s %-20s %-20s %-15s %-15s %-30s %-20s\n",
mac, apName, ssid, deviceType, dayZeroDC, deviceName, deviceVendor)
count++
}
fmt.Println(strings.Repeat("-", 140))
if androidOnly {
fmt.Printf("Total Android devices: %d\n", count)
} else {
fmt.Printf("Total clients: %d (Android: %d)\n", count, androidCount)
}
return rows.Err()
}

716
oui.go Normal file
View File

@@ -0,0 +1,716 @@
package main
var androidManufacturerOUIs = map[string]string{
"00:08:22": "Samsung",
"00:12:47": "Samsung",
"00:12:fb": "Samsung",
"00:13:77": "Samsung",
"00:15:b9": "Samsung",
"00:16:32": "Samsung",
"00:16:6b": "Samsung",
"00:16:6c": "Samsung",
"00:17:c9": "Samsung",
"00:17:d5": "Samsung",
"00:18:af": "Samsung",
"00:1a:8a": "Samsung",
"00:1b:98": "Samsung",
"00:1c:43": "Samsung",
"00:1d:25": "Samsung",
"00:1d:f6": "Samsung",
"00:1e:7d": "Samsung",
"00:1e:e1": "Samsung",
"00:1e:e2": "Samsung",
"00:21:19": "Samsung",
"00:21:4c": "Samsung",
"00:21:d1": "Samsung",
"00:21:d2": "Samsung",
"00:23:39": "Samsung",
"00:23:99": "Samsung",
"00:23:d6": "Samsung",
"00:23:d7": "Samsung",
"00:24:54": "Samsung",
"00:24:90": "Samsung",
"00:24:91": "Samsung",
"00:25:38": "Samsung",
"00:25:66": "Samsung",
"00:25:67": "Samsung",
"00:26:37": "Samsung",
"00:e0:64": "Samsung",
"08:08:c2": "Samsung",
"08:d4:2b": "Samsung",
"10:30:47": "Samsung",
"10:77:b1": "Samsung",
"18:3a:2d": "Samsung",
"18:3f:47": "Samsung",
"18:46:17": "Samsung",
"18:e2:c2": "Samsung",
"1c:5a:3e": "Samsung",
"1c:62:b8": "Samsung",
"1c:66:aa": "Samsung",
"20:13:e0": "Samsung",
"20:64:32": "Samsung",
"20:a6:cd": "Samsung",
"24:da:33": "Samsung",
"28:39:5e": "Samsung",
"28:3d:c2": "Samsung",
"28:ba:b5": "Samsung",
"2c:44:01": "Samsung",
"2c:44:fd": "Samsung",
"30:19:66": "Samsung",
"30:cd:a7": "Samsung",
"34:23:ba": "Samsung",
"34:aa:8b": "Samsung",
"38:0a:94": "Samsung",
"38:aa:3c": "Samsung",
"3c:5a:37": "Samsung",
"40:0e:85": "Samsung",
"40:23:43": "Samsung",
"40:4d:8e": "Samsung",
"40:b0:fa": "Samsung",
"44:4e:1a": "Samsung",
"44:6d:57": "Samsung",
"48:5a:3f": "Samsung",
"4c:bc:a5": "Samsung",
"50:32:37": "Samsung",
"50:a4:c8": "Samsung",
"50:cc:f8": "Samsung",
"54:88:0e": "Samsung",
"58:21:05": "Samsung",
"5c:0a:5b": "Samsung",
"5c:0e:8b": "Samsung",
"5c:3c:27": "Samsung",
"5c:51:88": "Samsung",
"5c:f6:dc": "Samsung",
"60:6b:bd": "Samsung",
"60:a1:0a": "Samsung",
"60:d0:a9": "Samsung",
"64:16:f0": "Samsung",
"64:77:91": "Samsung",
"64:b3:10": "Samsung",
"68:9c:5e": "Samsung",
"68:a3:78": "Samsung",
"68:eb:ae": "Samsung",
"6c:2f:2c": "Samsung",
"6c:40:08": "Samsung",
"6c:50:4d": "Samsung",
"6c:94:f8": "Samsung",
"70:2a:d5": "Samsung",
"70:5a:0f": "Samsung",
"74:45:8a": "Samsung",
"74:5f:00": "Samsung",
"78:1f:db": "Samsung",
"78:25:ad": "Samsung",
"78:40:e4": "Samsung",
"78:47:1d": "Samsung",
"78:52:1a": "Samsung",
"78:59:5e": "Samsung",
"78:9e:d0": "Samsung",
"78:a8:73": "Samsung",
"78:d6:f0": "Samsung",
"7c:11:be": "Samsung",
"7c:61:66": "Samsung",
"7c:b0:c2": "Samsung",
"80:18:a7": "Samsung",
"84:00:d2": "Samsung",
"84:11:9e": "Samsung",
"84:25:db": "Samsung",
"84:38:38": "Samsung",
"88:30:8a": "Samsung",
"88:32:9b": "Samsung",
"88:9b:39": "Samsung",
"8c:77:12": "Samsung",
"8c:c8:cd": "Samsung",
"90:18:7c": "Samsung",
"94:35:0a": "Samsung",
"94:d7:29": "Samsung",
"98:52:b1": "Samsung",
"98:83:89": "Samsung",
"9c:02:98": "Samsung",
"9c:3a:af": "Samsung",
"9c:e6:e7": "Samsung",
"a0:07:98": "Samsung",
"a0:0b:ba": "Samsung",
"a0:21:95": "Samsung",
"a0:75:91": "Samsung",
"a4:eb:d3": "Samsung",
"a8:7c:01": "Samsung",
"a8:f2:74": "Samsung",
"ac:36:13": "Samsung",
"ac:5f:3e": "Samsung",
"b0:72:bf": "Samsung",
"b0:c5:59": "Samsung",
"b0:ec:71": "Samsung",
"b4:07:f9": "Samsung",
"b4:ef:39": "Samsung",
"b8:5e:7b": "Samsung",
"b8:c6:8e": "Samsung",
"bc:20:ba": "Samsung",
"bc:72:b1": "Samsung",
"bc:85:1f": "Samsung",
"bc:b1:f3": "Samsung",
"c0:65:99": "Samsung",
"c0:bd:d1": "Samsung",
"c4:42:02": "Samsung",
"c4:57:6e": "Samsung",
"c8:19:f7": "Samsung",
"c8:a8:23": "Samsung",
"cc:07:ab": "Samsung",
"cc:3a:61": "Samsung",
"cc:fe:3c": "Samsung",
"d0:17:6a": "Samsung",
"d0:22:be": "Samsung",
"d0:59:e4": "Samsung",
"d0:66:7b": "Samsung",
"d0:87:e2": "Samsung",
"d4:87:d8": "Samsung",
"d4:e8:b2": "Samsung",
"d8:31:cf": "Samsung",
"d8:57:ef": "Samsung",
"d8:90:e8": "Samsung",
"d8:c4:6a": "Samsung",
"dc:71:44": "Samsung",
"e4:12:1d": "Samsung",
"e4:32:cb": "Samsung",
"e4:40:e2": "Samsung",
"e4:92:fb": "Samsung",
"e8:03:9a": "Samsung",
"e8:11:32": "Samsung",
"e8:50:8b": "Samsung",
"e8:e5:d6": "Samsung",
"ec:1d:8b": "Samsung",
"ec:9b:f3": "Samsung",
"f0:08:d1": "Samsung",
"f0:25:b7": "Samsung",
"f0:5a:09": "Samsung",
"f0:72:8c": "Samsung",
"f4:09:d8": "Samsung",
"f4:7b:5e": "Samsung",
"f4:d9:fb": "Samsung",
"f8:04:2e": "Samsung",
"f8:d0:bd": "Samsung",
"fc:00:12": "Samsung",
"fc:a1:3e": "Samsung",
"fc:c7:34": "Samsung",
"00:1b:63": "Huawei",
"00:1e:10": "Huawei",
"00:25:9e": "Huawei",
"00:46:4b": "Huawei",
"00:66:4b": "Huawei",
"00:9a:cd": "Huawei",
"00:e0:fc": "Huawei",
"04:02:1f": "Huawei",
"04:33:89": "Huawei",
"04:4f:aa": "Huawei",
"04:c0:6f": "Huawei",
"08:19:a6": "Huawei",
"08:7a:4c": "Huawei",
"0c:37:dc": "Huawei",
"0c:96:bf": "Huawei",
"10:1b:54": "Huawei",
"10:47:80": "Huawei",
"10:51:72": "Huawei",
"10:c6:1f": "Huawei",
"14:75:90": "Huawei",
"14:b9:68": "Huawei",
"18:0d:2c": "Huawei",
"18:4f:32": "Huawei",
"18:99:35": "Huawei",
"1c:1d:67": "Huawei",
"1c:48:55": "Huawei",
"20:08:ed": "Huawei",
"20:f3:a3": "Huawei",
"24:09:95": "Huawei",
"24:44:27": "Huawei",
"24:69:a5": "Huawei",
"24:7f:20": "Huawei",
"24:db:ac": "Huawei",
"28:31:52": "Huawei",
"28:6e:d4": "Huawei",
"2c:1d:b8": "Huawei",
"2c:ab:a4": "Huawei",
"30:3a:64": "Huawei",
"30:87:d9": "Huawei",
"34:6b:d3": "Huawei",
"34:cd:be": "Huawei",
"38:83:45": "Huawei",
"3c:fa:43": "Huawei",
"40:4d:7f": "Huawei",
"40:b0:34": "Huawei",
"44:00:4d": "Huawei",
"44:6e:e5": "Huawei",
"48:46:fb": "Huawei",
"48:7b:6b": "Huawei",
"4c:54:99": "Huawei",
"4c:b1:6c": "Huawei",
"50:01:bb": "Huawei",
"50:7b:9d": "Huawei",
"54:25:ea": "Huawei",
"54:89:98": "Huawei",
"58:2a:f7": "Huawei",
"5c:63:bf": "Huawei",
"60:de:44": "Huawei",
"64:3e:8c": "Huawei",
"64:a6:51": "Huawei",
"68:3e:34": "Huawei",
"6c:4a:85": "Huawei",
"6c:92:bf": "Huawei",
"70:54:f5": "Huawei",
"74:a5:28": "Huawei",
"78:02:f8": "Huawei",
"78:6a:89": "Huawei",
"78:d7:52": "Huawei",
"7c:60:97": "Huawei",
"7c:a2:3e": "Huawei",
"80:38:bc": "Huawei",
"80:71:7a": "Huawei",
"80:d0:9b": "Huawei",
"84:a8:e4": "Huawei",
"88:28:b3": "Huawei",
"88:cf:98": "Huawei",
"8c:0e:e3": "Huawei",
"90:17:ac": "Huawei",
"94:04:9c": "Huawei",
"98:52:3d": "Huawei",
"9c:28:ef": "Huawei",
"9c:37:f4": "Huawei",
"9c:52:f8": "Huawei",
"9c:a9:f4": "Huawei",
"a0:c5:89": "Huawei",
"a4:39:b3": "Huawei",
"a4:c4:94": "Huawei",
"a8:16:b2": "Huawei",
"ac:4e:91": "Huawei",
"ac:5f:ea": "Huawei",
"ac:85:3d": "Huawei",
"b0:e5:ed": "Huawei",
"b4:cd:27": "Huawei",
"b8:08:cf": "Huawei",
"bc:25:e0": "Huawei",
"bc:76:70": "Huawei",
"c0:18:50": "Huawei",
"c4:0b:cb": "Huawei",
"c8:14:79": "Huawei",
"c8:6c:87": "Huawei",
"cc:96:a0": "Huawei",
"d0:7a:b5": "Huawei",
"d4:6a:6a": "Huawei",
"d4:6e:5c": "Huawei",
"d4:f9:a1": "Huawei",
"d8:49:0b": "Huawei",
"d8:c7:71": "Huawei",
"dc:d9:16": "Huawei",
"e0:19:1d": "Huawei",
"e0:97:96": "Huawei",
"e4:d3:32": "Huawei",
"e8:cd:2d": "Huawei",
"ec:23:3d": "Huawei",
"ec:38:8f": "Huawei",
"f0:b4:29": "Huawei",
"f4:4e:e3": "Huawei",
"f4:c7:14": "Huawei",
"f8:4a:bf": "Huawei",
"f8:a4:5f": "Huawei",
"fc:48:ef": "Huawei",
"00:23:cd": "OnePlus",
"08:05:81": "OnePlus",
"08:be:ac": "OnePlus",
"0c:8d:db": "OnePlus",
"10:2c:6b": "OnePlus",
"14:7d:c5": "OnePlus",
"1c:9e:46": "OnePlus",
"20:7d:74": "OnePlus",
"28:5f:db": "OnePlus",
"2c:6d:c1": "OnePlus",
"30:e1:71": "OnePlus",
"34:13:e8": "OnePlus",
"38:0b:40": "OnePlus",
"3c:39:e7": "OnePlus",
"40:4e:36": "OnePlus",
"48:e1:e9": "OnePlus",
"4c:bb:58": "OnePlus",
"50:af:73": "OnePlus",
"54:35:30": "OnePlus",
"58:00:e3": "OnePlus",
"5c:86:c0": "OnePlus",
"60:be:b5": "OnePlus",
"64:a2:f9": "OnePlus",
"68:3e:26": "OnePlus",
"6c:24:08": "OnePlus",
"70:66:55": "OnePlus",
"74:4e:af": "OnePlus",
"78:44:05": "OnePlus",
"7c:c2:c6": "OnePlus",
"80:84:28": "OnePlus",
"88:6b:0f": "OnePlus",
"8c:89:a5": "OnePlus",
"90:b6:86": "OnePlus",
"94:65:2d": "OnePlus",
"98:54:1b": "OnePlus",
"9c:b6:d0": "OnePlus",
"a0:63:91": "OnePlus",
"a4:50:46": "OnePlus",
"a8:5b:78": "OnePlus",
"ac:37:43": "OnePlus",
"b0:a7:32": "OnePlus",
"b4:0e:de": "OnePlus",
"b8:86:87": "OnePlus",
"bc:f1:71": "OnePlus",
"c0:ee:fb": "OnePlus",
"c4:07:2f": "OnePlus",
"c8:28:32": "OnePlus",
"cc:2d:8c": "OnePlus",
"d0:53:49": "OnePlus",
"d4:6a:a8": "OnePlus",
"dc:2c:26": "OnePlus",
"e0:b5:5f": "OnePlus",
"e4:70:b8": "OnePlus",
"e8:b2:ac": "OnePlus",
"ec:d0:9f": "OnePlus",
"f0:27:2d": "OnePlus",
"f4:0f:24": "OnePlus",
"f8:8c:21": "OnePlus",
"fc:69:47": "OnePlus",
"00:08:9b": "Xiaomi",
"00:9e:c8": "Xiaomi",
"04:0b:76": "Xiaomi",
"04:33:c2": "Xiaomi",
"04:cf:4b": "Xiaomi",
"08:d4:6a": "Xiaomi",
"0c:1d:af": "Xiaomi",
"10:2a:b3": "Xiaomi",
"14:f6:5a": "Xiaomi",
"18:59:36": "Xiaomi",
"1c:1b:0d": "Xiaomi",
"20:34:fb": "Xiaomi",
"28:6c:07": "Xiaomi",
"28:e3:1f": "Xiaomi",
"2c:3a:fd": "Xiaomi",
"34:80:b3": "Xiaomi",
"34:ce:00": "Xiaomi",
"38:a4:ed": "Xiaomi",
"3c:bd:d8": "Xiaomi",
"40:31:3c": "Xiaomi",
"40:5d:82": "Xiaomi",
"50:64:2b": "Xiaomi",
"50:8f:4c": "Xiaomi",
"58:44:98": "Xiaomi",
"58:a9:d7": "Xiaomi",
"5c:c3:07": "Xiaomi",
"64:09:80": "Xiaomi",
"64:b4:73": "Xiaomi",
"68:df:dd": "Xiaomi",
"6c:56:97": "Xiaomi",
"74:23:44": "Xiaomi",
"74:51:ba": "Xiaomi",
"78:02:b7": "Xiaomi",
"78:11:dc": "Xiaomi",
"7c:1d:d9": "Xiaomi",
"7c:49:eb": "Xiaomi",
"80:35:c1": "Xiaomi",
"80:e6:50": "Xiaomi",
"88:c3:97": "Xiaomi",
"8c:be:be": "Xiaomi",
"90:17:9b": "Xiaomi",
"98:fa:e3": "Xiaomi",
"9c:99:a0": "Xiaomi",
"a0:86:c6": "Xiaomi",
"a4:08:ea": "Xiaomi",
"ac:c1:ee": "Xiaomi",
"b0:e2:35": "Xiaomi",
"b4:0b:44": "Xiaomi",
"c8:ff:77": "Xiaomi",
"d0:c5:d3": "Xiaomi",
"d4:97:0b": "Xiaomi",
"e0:b9:4d": "Xiaomi",
"e4:46:da": "Xiaomi",
"f4:8b:32": "Xiaomi",
"f4:f5:24": "Xiaomi",
"f8:59:71": "Xiaomi",
"fc:64:ba": "Xiaomi",
"00:1f:e1": "Google",
"00:1a:11": "Google",
"3c:5a:b4": "Google",
"54:60:09": "Google",
"68:c4:4d": "Google",
"6c:ad:f8": "Google",
"74:e5:43": "Google",
"84:cf:bf": "Google",
"b4:f0:ab": "Google",
"c4:43:8f": "Google",
"d4:f4:6f": "Google",
"dc:a6:32": "Google",
"f4:f5:e8": "Google",
"00:1c:62": "LG",
"00:1d:e5": "LG",
"00:1e:75": "LG",
"00:1f:6b": "LG",
"00:21:fb": "LG",
"00:22:a9": "LG",
"00:24:83": "LG",
"00:25:e5": "LG",
"00:26:e2": "LG",
"10:68:3f": "LG",
"18:80:f5": "LG",
"1c:b0:94": "LG",
"20:21:a5": "LG",
"34:fc:b9": "LG",
"40:b8:9a": "LG",
"48:5a:b6": "LG",
"54:33:cb": "LG",
"58:a2:b5": "LG",
"64:bc:0c": "LG",
"68:a0:f6": "LG",
"6c:d6:8a": "LG",
"78:5d:c8": "LG",
"88:c9:d0": "LG",
"a0:39:f7": "LG",
"b4:e1:c4": "LG",
"d0:13:fd": "LG",
"e8:5b:5b": "LG",
"f8:95:c7": "LG",
"00:1c:cc": "OPPO",
"08:26:ae": "OPPO",
"0c:84:dc": "OPPO",
"10:07:b6": "OPPO",
"14:9f:3c": "OPPO",
"1c:99:4c": "OPPO",
"20:47:ed": "OPPO",
"24:ee:9a": "OPPO",
"28:c6:3f": "OPPO",
"2c:54:cf": "OPPO",
"30:ae:7b": "OPPO",
"34:2e:b6": "OPPO",
"38:78:62": "OPPO",
"3c:bd:3e": "OPPO",
"40:33:1a": "OPPO",
"44:03:2c": "OPPO",
"48:0e:ec": "OPPO",
"4c:1f:cc": "OPPO",
"50:46:5d": "OPPO",
"54:27:1e": "OPPO",
"58:52:8a": "OPPO",
"60:ab:14": "OPPO",
"00:0c:e5": "Motorola",
"00:11:1a": "Motorola",
"00:12:25": "Motorola",
"00:13:71": "Motorola",
"00:14:9a": "Motorola",
"00:15:9a": "Motorola",
"00:16:26": "Motorola",
"00:17:84": "Motorola",
"00:18:c0": "Motorola",
"00:19:2c": "Motorola",
"00:1a:1b": "Motorola",
"00:1a:66": "Motorola",
"00:1a:77": "Motorola",
"00:1a:ad": "Motorola",
"00:1a:db": "Motorola",
"00:1b:52": "Motorola",
"00:1c:11": "Motorola",
"00:1c:fb": "Motorola",
"00:1d:6e": "Motorola",
"00:1e:46": "Motorola",
"00:1e:5a": "Motorola",
"00:1f:c4": "Motorola",
"00:21:1e": "Motorola",
"00:23:0b": "Motorola",
"00:23:75": "Motorola",
"00:23:ae": "Motorola",
"00:24:37": "Motorola",
"00:24:a0": "Motorola",
"00:25:4d": "Motorola",
"00:26:ba": "Motorola",
"04:a8:1c": "Motorola",
"08:ed:b9": "Motorola",
"0c:d6:96": "Motorola",
"10:0d:7f": "Motorola",
"1c:ab:a7": "Motorola",
"20:7c:8f": "Motorola",
"28:ed:6a": "Motorola",
"2c:36:f8": "Motorola",
"30:75:12": "Motorola",
"34:08:bc": "Motorola",
"3c:75:4a": "Motorola",
"40:98:4e": "Motorola",
"44:4c:0c": "Motorola",
"48:2c:ea": "Motorola",
"4c:0b:be": "Motorola",
"50:e0:85": "Motorola",
"54:42:49": "Motorola",
"58:c3:8b": "Motorola",
"60:38:e0": "Motorola",
"64:a7:69": "Motorola",
"68:ef:43": "Motorola",
"6c:88:14": "Motorola",
"70:db:98": "Motorola",
"74:e5:f9": "Motorola",
"78:4b:87": "Motorola",
"7c:d1:c3": "Motorola",
"80:d2:1d": "Motorola",
"84:68:78": "Motorola",
"88:9f:fa": "Motorola",
"8c:3a:e3": "Motorola",
"90:67:1c": "Motorola",
"94:eb:cd": "Motorola",
"98:0c:82": "Motorola",
"9c:b7:0d": "Motorola",
"a0:2c:36": "Motorola",
"a4:08:f5": "Motorola",
"a8:7e:33": "Motorola",
"ac:5a:14": "Motorola",
"b0:f1:a3": "Motorola",
"b4:52:7d": "Motorola",
"b8:27:eb": "Motorola",
"bc:92:6d": "Motorola",
"c0:84:7d": "Motorola",
"c4:62:ea": "Motorola",
"c8:0e:14": "Motorola",
"cc:c3:ea": "Motorola",
"d4:01:29": "Motorola",
"d8:00:4d": "Motorola",
"dc:71:96": "Motorola",
"e0:06:e6": "Motorola",
"e4:83:99": "Motorola",
"e8:04:0b": "Motorola",
"ec:10:7b": "Motorola",
"f0:d7:aa": "Motorola",
"f4:c7:95": "Motorola",
"f8:7b:7a": "Motorola",
"00:1c:b3": "HTC",
"00:23:76": "HTC",
"04:f7:e4": "HTC",
"08:66:98": "HTC",
"18:87:96": "HTC",
"20:68:9d": "HTC",
"38:e7:d8": "HTC",
"54:a0:50": "HTC",
"7c:61:93": "HTC",
"80:c5:f2": "HTC",
"84:7a:88": "HTC",
"90:21:55": "HTC",
"a4:17:31": "HTC",
"b4:ce:f6": "HTC",
"c4:85:08": "HTC",
"d4:94:e8": "HTC",
"e8:99:c4": "HTC",
"f8:db:7f": "HTC",
"00:1f:5b": "Sony",
"00:22:98": "Sony",
"00:23:12": "Sony",
"00:24:be": "Sony",
"04:5a:13": "Sony",
"08:6d:41": "Sony",
"0c:fe:45": "Sony",
"10:4f:a8": "Sony",
"20:02:af": "Sony",
"24:0a:64": "Sony",
"28:a0:2b": "Sony",
"2c:1f:23": "Sony",
"30:39:26": "Sony",
"3c:77:e6": "Sony",
"40:2b:a1": "Sony",
"44:07:0b": "Sony",
"48:60:5f": "Sony",
"4c:34:88": "Sony",
"50:55:27": "Sony",
"58:17:0c": "Sony",
"5c:f8:a1": "Sony",
"60:d4:f7": "Sony",
"68:9c:70": "Sony",
"70:1c:e7": "Sony",
"74:90:50": "Sony",
"78:1d:ba": "Sony",
"88:75:56": "Sony",
"8c:64:22": "Sony",
"90:48:9a": "Sony",
"94:d0:29": "Sony",
"98:e0:d9": "Sony",
"9c:ad:97": "Sony",
"a0:e4:53": "Sony",
"a4:b8:05": "Sony",
"a8:86:dd": "Sony",
"ac:9b:0a": "Sony",
"b0:35:9f": "Sony",
"b4:52:7e": "Sony",
"b8:f9:34": "Sony",
"bc:60:a7": "Sony",
"c0:38:f9": "Sony",
"c4:73:1e": "Sony",
"c8:bc:c8": "Sony",
"cc:fa:00": "Sony",
"d4:4b:5e": "Sony",
"d8:6c:e9": "Sony",
"dc:a4:ca": "Sony",
"e0:75:7d": "Sony",
"e4:9a:79": "Sony",
"ec:a9:fa": "Sony",
"f0:27:65": "Sony",
"f4:0e:11": "Sony",
"f8:46:1c": "Sony",
"fc:f1:52": "Sony",
"00:1c:d4": "Asus",
"00:1f:c6": "Asus",
"00:22:15": "Asus",
"00:23:54": "Asus",
"00:24:8c": "Asus",
"00:25:d3": "Asus",
"00:26:18": "Asus",
"04:42:1a": "Asus",
"08:60:6e": "Asus",
"0c:9d:92": "Asus",
"10:bf:48": "Asus",
"14:dd:a9": "Asus",
"18:31:bf": "Asus",
"1c:87:2c": "Asus",
"20:cf:30": "Asus",
"24:4b:fe": "Asus",
"28:e3:47": "Asus",
"2c:fd:a1": "Asus",
"30:5a:3a": "Asus",
"34:97:f6": "Asus",
"38:d5:47": "Asus",
"3c:7c:3f": "Asus",
"40:16:7e": "Asus",
"44:a8:42": "Asus",
"48:5b:39": "Asus",
"4c:ed:fb": "Asus",
"58:11:22": "Asus",
"5c:33:8e": "Asus",
"60:45:cb": "Asus",
"64:51:7e": "Asus",
"68:05:ca": "Asus",
"6c:19:c0": "Asus",
"70:4d:7b": "Asus",
"74:d0:2b": "Asus",
"78:24:af": "Asus",
"7c:7a:91": "Asus",
"80:1f:02": "Asus",
"84:a6:c8": "Asus",
"88:d7:f6": "Asus",
"8c:10:d4": "Asus",
"94:de:80": "Asus",
"98:fc:11": "Asus",
"9c:5c:8e": "Asus",
"a0:f3:c1": "Asus",
"a4:5d:36": "Asus",
"a8:5e:45": "Asus",
"ac:22:0b": "Asus",
"b0:6e:bf": "Asus",
"b4:2e:99": "Asus",
"b8:ee:65": "Asus",
"bc:ee:7b": "Asus",
"c0:3f:0e": "Asus",
"c8:60:00": "Asus",
"cc:2d:21": "Asus",
"d0:17:c2": "Asus",
"d4:6e:0e": "Asus",
"d8:50:e6": "Asus",
"dc:85:de": "Asus",
"e0:3f:49": "Asus",
"e8:94:f6": "Asus",
"ec:08:6b": "Asus",
"f0:79:59": "Asus",
"f4:6d:04": "Asus",
"f8:32:e4": "Asus",
"fc:34:97": "Asus",
}