mini controller

This commit is contained in:
Martin/Geno 2018-06-03 20:37:52 +02:00
parent 5cea0a4ca2
commit 7ed85511b0
No known key found for this signature in database
GPG Key ID: 9D7D3C6BFF600C6A
9 changed files with 226 additions and 2 deletions

View File

@ -95,6 +95,7 @@ func (coll *Collector) parser() {
log.Warnf("unable to unmarshal request from %s: %s", obj.Address.String(), err)
continue
}
log.Debugf("recv[%s]: %s", obj.Address, msg.String())
response, err := coll.handler(obj.Address, msg)
if err != nil {
log.Warnf("unable to handle request from %s: %s", obj.Address.String(), err)
@ -108,6 +109,7 @@ func (coll *Collector) parser() {
// SendTo a specifical address
func (coll *Collector) SendTo(addr *net.UDPAddr, msg *data.SocketMSG) {
log.Debugf("send[%s]: %s", addr, msg.String())
data, err := msg.Marshal()
if err != nil {
log.Warnf("unable to marshal response for %s: %s", addr.String(), err)
@ -125,6 +127,7 @@ func (coll *Collector) SendTo(addr *net.UDPAddr, msg *data.SocketMSG) {
// Send to every connection to default address
func (coll *Collector) Send(msg *data.SocketMSG) {
log.Debugf("send: %s", msg.String())
data, err := msg.Marshal()
if err != nil {
log.Warnf("unable to marshal response: %s", err)

67
cmd/controller.go Normal file
View File

@ -0,0 +1,67 @@
package cmd
import (
"os"
"os/signal"
"strings"
"syscall"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"dev.sum7.eu/wifictld/analyzer/capture"
"dev.sum7.eu/wifictld/analyzer/controller"
"dev.sum7.eu/wifictld/analyzer/database"
)
var (
central bool
)
// queryCmd represents the query command
var controllerCmd = &cobra.Command{
Use: "controller <interfaces>",
Short: "simulate a wifictld controller",
Example: `analyzer controller "eth0,wlan0"`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ifaces := strings.Split(args[0], ",")
log.Infof("listen on: %s", ifaces)
var ifacesConfigs []capture.IFaceConfig
for _, iface := range ifaces {
ifaceConfig := capture.IFaceConfig{
InterfaceName: iface,
Port: port,
IPAddress: ipAddress,
}
ifacesConfigs = append(ifacesConfigs, ifaceConfig)
}
db := database.NewDB()
ctr := controller.NewController(db, central)
defer ctr.Close()
coll := capture.NewCollector(ctr.Handler, ifacesConfigs)
defer coll.Close()
ctr.Send = coll.Send
ctr.SendTo = coll.SendTo
// Wait for INT/TERM
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
sig := <-sigs
log.Println("received", sig)
},
}
func init() {
RootCmd.AddCommand(controllerCmd)
controllerCmd.Flags().IntVar(&port, "port", capture.Port, "define a port to listen (if not set or set to 0 the kernel will use a random free port at its own)")
controllerCmd.Flags().StringVar(&ipAddress, "listen", capture.MulticastAddressDefault, "")
controllerCmd.Flags().BoolVar(&central, "central", false, "")
}

View File

@ -40,6 +40,8 @@ var dumpCmd = &cobra.Command{
ifacesConfigs = append(ifacesConfigs, ifaceConfig)
}
data.DEBUG = debug
coll := capture.NewCollector(func(addr *net.UDPAddr, msg *data.SocketMSG) (*data.SocketMSG, error) {
log.Infof("recv[%s]: %s", addr, msg.String())
return nil, nil

29
controller/handler.go Normal file
View File

@ -0,0 +1,29 @@
package controller
import (
"net"
// log "github.com/sirupsen/logrus"
"dev.sum7.eu/wifictld/analyzer/data"
)
func (c *Controller) Handler(addr *net.UDPAddr, msg *data.SocketMSG) (*data.SocketMSG, error) {
ignore := false
if msg.Types.Is(data.SocketMSGTypeClient) && msg.Client != nil {
ignore = c.db.LearnClient(addr.IP, msg.Client)
}
if !msg.Types.Is(data.SocketMSGTypeRequest) {
return nil, nil
}
msg = &data.SocketMSG{
Types: (data.SocketMSGTypeResponse | data.SocketMSGTypeClient),
Client: c.db.GetClient(msg.Client.Addr),
}
if c.central || !ignore {
return msg, nil
}
return nil, nil
}

39
controller/main.go Normal file
View File

@ -0,0 +1,39 @@
package controller
import (
"net"
"time"
log "github.com/sirupsen/logrus"
"dev.sum7.eu/wifictld/analyzer/data"
"dev.sum7.eu/wifictld/analyzer/database"
)
type Controller struct {
SendTo func(addr *net.UDPAddr, msg *data.SocketMSG)
Send func(msg *data.SocketMSG)
db *database.DB
ticker *time.Ticker
central bool
}
func NewController(db *database.DB, central bool) *Controller {
ctl := &Controller{
ticker: time.NewTicker(60 * time.Second),
db: db,
central: central,
}
go ctl.Repeated()
return ctl
}
func (c *Controller) Close() {
c.ticker.Stop()
}
func (c *Controller) Repeated() {
for range c.ticker.C {
log.Infof("lerned: %d APs, %d Clients", len(c.db.APs), len(c.db.Clients))
}
}

View File

@ -9,6 +9,8 @@ import (
log "github.com/sirupsen/logrus"
)
var DEBUG = false
// SocketMSGType kind of packages
type SocketMSGType uint32
@ -20,7 +22,10 @@ const (
)
func (a SocketMSGType) Is(b SocketMSGType) bool {
log.Debugf("SocketType: %x & %x = %x -> %b", a, b, (a & b), (a&b) > 0)
if DEBUG {
log.Debugf("SocketType: %x & %x = %x -> %b", a, b, (a & b), (a&b) > 0)
}
return (a & b) > 0
}
@ -84,7 +89,9 @@ func (msg *SocketMSG) Marshal() ([]byte, error) {
}
func (msg *SocketMSG) Unmarshal(obj []byte) error {
log.Debugf("hex unmarshal: %x", obj)
if DEBUG {
log.Debugf("hex unmarshal: %x", obj)
}
pos := 0

4
database/ap.go Normal file
View File

@ -0,0 +1,4 @@
package database
type AP struct {
}

60
database/client.go Normal file
View File

@ -0,0 +1,60 @@
package database
import (
"net"
"time"
// log "github.com/sirupsen/logrus"
"dev.sum7.eu/wifictld/analyzer/data"
)
type Client struct {
Addr net.HardwareAddr
Time time.Time
TryProbe uint16
TryAuth uint16
Connected bool
Authed bool
FreqHighest uint16
SignalLowFreq int16
SignalHighFreq int16
}
func (db *DB) LearnClient(apIP net.IP, clientWifictl *data.WifiClient) bool {
ret := false
apAddr := apIP.String()
ap, ok := db.APs[apAddr]
if !ok {
ap = &AP{}
db.APs[apAddr] = ap
}
clientAddr := clientWifictl.Addr.String()
client, ok := db.Clients[clientAddr]
if !ok {
client = &Client{
Addr: clientWifictl.Addr,
}
db.Clients[clientAddr] = client
}
client.Time = time.Now()
if client.FreqHighest < clientWifictl.FreqHighest {
ret = (client.FreqHighest != 0)
client.FreqHighest = clientWifictl.FreqHighest
}
return ret
}
func (db *DB) GetClient(addr net.HardwareAddr) *data.WifiClient {
client, ok := db.Clients[addr.String()]
wClient := &data.WifiClient{
Addr: addr,
Time: time.Now(),
}
if ok {
wClient.TryProbe = client.TryProbe
}
return wClient
}

13
database/main.go Normal file
View File

@ -0,0 +1,13 @@
package database
type DB struct {
Clients map[string]*Client `json:"client"`
APs map[string]*AP `json:"ap"`
}
func NewDB() *DB {
return &DB{
Clients: make(map[string]*Client),
APs: make(map[string]*AP),
}
}