--- a/bin/pvl.wlan-sta Fri Jul 05 00:59:56 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-#!/usr/bin/python
-
-"""
- Analyze WLAN STA logs.
-
- Jul 3 23:05:04 buffalo-g300n-647682 daemon.info hostapd: wlan0-1: STA aa:bb:cc:dd:ee:ff WPA: group key handshake completed (RSN)
-
-"""
-
-__version__ = '0.1'
-
-import pvl.args
-import pvl.syslog.args
-import pvl.rrd.hosts
-
-import optparse
-import logging; log = logging.getLogger('main')
-
-WLAN_STA_PROG = 'hostapd'
-
-def parse_argv (argv, doc = __doc__) :
- """
- Parse command-line argv, returning (options, args).
- """
-
- prog = argv.pop(0)
- args = argv
-
- # optparse
- parser = optparse.OptionParser(
- prog = prog,
- usage = '%prog: [options] [<input.txt> [...]]',
- version = __version__,
- description = doc,
- )
-
- # common
- parser.add_option_group(pvl.args.parser(parser))
- parser.add_option_group(pvl.syslog.args.parser(parser, prog=WLAN_STA_PROG))
- parser.add_option_group(pvl.verkko.db.parser(parser, table=db.wlan_sta))
-
- parser.add_option('--interfaces', metavar='PATH',
- help="Load interface/node names from mapping file")
-
- # parse
- options, args = parser.parse_args(args)
-
- # apply
- pvl.args.apply(options)
-
- return options, args
-
-import re
-from pvl.verkko import db
-
-class WlanStaDatabase (object) :
- HOSTAPD_STA_RE = re.compile(r'(?P<wlan>.+?): STA (?P<sta>.+?) (?P<msg>.+)')
-
- DB_TABLE = db.wlan_sta
- DB_LAST_SEEN = db.wlan_sta.c.last_seen
- DB_SELECT = (db.dhcp_hosts.c.gw, db.dhcp_hosts.c.ip)
-
- def __init__ (self, db, interface_map=None) :
- """
- interface_map - {(hostname, interface): (nodename, wlan)}
- """
- self.db = db
- self.interface_map = interface_map
-
-
- def select (self, distinct=DB_SELECT, interval=None) :
- """
- SELECT unique gw/ip hosts, for given interval.
- """
-
- query = db.select(distinct, distinct=True)
-
- if interval :
- # timedelta
- query = query.where(db.func.now() - self.DB_LAST_SEEN < interval)
-
- return self.db.select(query)
-
- def insert (self, key, update, timestamp, count=True) :
- """
- INSERT new host
- """
-
- query = self.DB_TABLE.insert().values(**key).values(**update).values(
- first_seen = timestamp,
- last_seen = timestamp,
- )
-
- if count :
- query = query.values(count=1)
-
- # -> id
- return self.db.insert(query)
-
- def update (self, key, update, timestamp, count=True) :
- """
- UPDATE existing host, or return False if not found.
- """
-
- table = self.DB_TABLE
- query = table.update()
-
- for col, value in key.iteritems() :
- query = query.where(table.c[col] == value)
-
- query = query.values(last_seen=timestamp)
-
- if count :
- query = query.values(count=db.func.coalesce(table.c.count, 0) + 1)
-
- query = query.values(**update)
-
- # -> any matched rows?
- return self.db.update(query)
-
- def touch (self, key, update, timestamp, **opts) :
- # update existing?
- if self.update(key, update, timestamp, **opts) :
- log.info("Update: %s: %s: %s", key, update, timestamp)
- else :
- log.info("Insert: %s: %s: %s", key, update, timestamp)
- self.insert(key, update, timestamp, **opts)
-
- def parse (self, item) :
- """
- Parse fields from a hostapd syslog message.
- """
-
- match = self.HOSTAPD_STA_RE.match(item['msg'])
-
- if not match :
- return None
-
- return match.groupdict()
-
- def __call__ (self, item) :
- match = self.parse(item)
-
- if not match :
- return
-
- # lookup?
- ap, wlan = item['host'], match['wlan']
-
- if self.interface_map :
- mapping = self.interface_map.get((ap, wlan))
-
- if mapping :
- ap, wlan = mapping
-
- # update/insert
- self.touch(
- dict(
- ap = ap,
- wlan = wlan,
- sta = match['sta'],
- ), dict(
- msg = match['msg'],
- ), item['timestamp']
- )
-
-def main (argv) :
- options, args = parse_argv(argv)
-
- # database
- db = pvl.verkko.db.apply(options)
-
- if options.interfaces :
- interfaces = dict(pvl.rrd.hosts.map_interfaces(options, open(options.interfaces)))
- else :
- interfaces = None
-
- # syslog
- log.info("Open up syslog...")
- syslog = pvl.syslog.args.apply(options)
-
- # handler
- handler = WlanStaDatabase(db, interface_map=interfaces)
-
- log.info("Enter mainloop...")
- for source in syslog.main() :
- for item in source:
- handler(item)
-
- return 0
-
-if __name__ == '__main__':
- import sys
-
- sys.exit(main(sys.argv))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/pvl.wlan-syslog Fri Jul 05 01:01:14 2013 +0300
@@ -0,0 +1,194 @@
+#!/usr/bin/python
+
+"""
+ Analyze WLAN STA logs.
+
+ Jul 3 23:05:04 buffalo-g300n-647682 daemon.info hostapd: wlan0-1: STA aa:bb:cc:dd:ee:ff WPA: group key handshake completed (RSN)
+
+"""
+
+__version__ = '0.1'
+
+import pvl.args
+import pvl.syslog.args
+import pvl.rrd.hosts
+
+import optparse
+import logging; log = logging.getLogger('main')
+
+WLAN_STA_PROG = 'hostapd'
+
+def parse_argv (argv, doc = __doc__) :
+ """
+ Parse command-line argv, returning (options, args).
+ """
+
+ prog = argv.pop(0)
+ args = argv
+
+ # optparse
+ parser = optparse.OptionParser(
+ prog = prog,
+ usage = '%prog: [options] [<input.txt> [...]]',
+ version = __version__,
+ description = doc,
+ )
+
+ # common
+ parser.add_option_group(pvl.args.parser(parser))
+ parser.add_option_group(pvl.syslog.args.parser(parser, prog=WLAN_STA_PROG))
+ parser.add_option_group(pvl.verkko.db.parser(parser, table=db.wlan_sta))
+
+ parser.add_option('--interfaces', metavar='PATH',
+ help="Load interface/node names from mapping file")
+
+ # parse
+ options, args = parser.parse_args(args)
+
+ # apply
+ pvl.args.apply(options)
+
+ return options, args
+
+import re
+from pvl.verkko import db
+
+class WlanStaDatabase (object) :
+ HOSTAPD_STA_RE = re.compile(r'(?P<wlan>.+?): STA (?P<sta>.+?) (?P<msg>.+)')
+
+ DB_TABLE = db.wlan_sta
+ DB_LAST_SEEN = db.wlan_sta.c.last_seen
+ DB_SELECT = (db.dhcp_hosts.c.gw, db.dhcp_hosts.c.ip)
+
+ def __init__ (self, db, interface_map=None) :
+ """
+ interface_map - {(hostname, interface): (nodename, wlan)}
+ """
+ self.db = db
+ self.interface_map = interface_map
+
+ def select (self, distinct=DB_SELECT, interval=None) :
+ """
+ SELECT unique gw/ip hosts, for given interval.
+ """
+
+ query = db.select(distinct, distinct=True)
+
+ if interval :
+ # timedelta
+ query = query.where(db.func.now() - self.DB_LAST_SEEN < interval)
+
+ return self.db.select(query)
+
+ def insert (self, key, update, timestamp, count=True) :
+ """
+ INSERT new host
+ """
+
+ query = self.DB_TABLE.insert().values(**key).values(**update).values(
+ first_seen = timestamp,
+ last_seen = timestamp,
+ )
+
+ if count :
+ query = query.values(count=1)
+
+ # -> id
+ return self.db.insert(query)
+
+ def update (self, key, update, timestamp, count=True) :
+ """
+ UPDATE existing host, or return False if not found.
+ """
+
+ table = self.DB_TABLE
+ query = table.update()
+
+ for col, value in key.iteritems() :
+ query = query.where(table.c[col] == value)
+
+ query = query.values(last_seen=timestamp)
+
+ if count :
+ query = query.values(count=db.func.coalesce(table.c.count, 0) + 1)
+
+ query = query.values(**update)
+
+ # -> any matched rows?
+ return self.db.update(query)
+
+ def touch (self, key, update, timestamp, **opts) :
+ # update existing?
+ if self.update(key, update, timestamp, **opts) :
+ log.info("Update: %s: %s: %s", key, update, timestamp)
+ else :
+ log.info("Insert: %s: %s: %s", key, update, timestamp)
+ self.insert(key, update, timestamp, **opts)
+
+ def parse (self, item) :
+ """
+ Parse fields from a hostapd syslog message.
+ """
+
+ match = self.HOSTAPD_STA_RE.match(item['msg'])
+
+ if not match :
+ return None
+
+ return match.groupdict()
+
+ def __call__ (self, item) :
+ match = self.parse(item)
+
+ if not match :
+ return
+
+ # lookup?
+ ap, wlan = item['host'], match['wlan']
+
+ if self.interface_map :
+ mapping = self.interface_map.get((ap, wlan))
+
+ if mapping :
+ ap, wlan = mapping
+
+ # update/insert
+ self.touch(
+ dict(
+ ap = ap,
+ wlan = wlan,
+ sta = match['sta'],
+ ), dict(
+ msg = match['msg'],
+ ), item['timestamp']
+ )
+
+def main (argv) :
+ options, args = parse_argv(argv)
+
+ # database
+ db = pvl.verkko.db.apply(options)
+
+ if options.interfaces :
+ interfaces = dict(pvl.rrd.hosts.map_interfaces(options, open(options.interfaces)))
+ else :
+ interfaces = None
+
+ # syslog
+ log.info("Open up syslog...")
+ syslog = pvl.syslog.args.apply(options)
+
+ # handler
+ handler = WlanStaDatabase(db, interface_map=interfaces)
+
+ log.info("Enter mainloop...")
+ for source in syslog.main() :
+ for item in source:
+ handler(item)
+
+ return 0
+
+if __name__ == '__main__':
+ import sys
+
+ sys.exit(main(sys.argv))