Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- #
- # Parse arpwatch log file and store into MySQL database
- # Copyright (C) 2013 Stjepan Groš <stjepan.gros@gmail.com>
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- #
- # Version 20130312
- # - Initial version
- import sys
- from datetime import datetime^
- import MySQLdb
- from socket import inet_aton
- import struct
- import ConfigParser
- CONFIGFILE="arpwatchlog2sql.conf"
- def normalizemac(mac):
- digitsStr = mac.split(':')
- digits = [ int(x, 16) for x in digitsStr ]
- digitsStr = "%02x:%02x:%02x:%02x:%02x:%02x" % tuple(digits)
- return digitsStr
- def ip2int(ip):
- nums = ip.split('.')
- return int(nums[0])*256**3 + int(nums[1])*256**2 + int(nums[2])*256 + int(nums[3])
- def main(args):
- config = ConfigParser.RawConfigParser()
- config.read(CONFIGFILE)
- LOGFILE = config.get("Main", "LOGFILE")
- STATEFILE = config.get("Main", "STATEFILE")
- dbHost = config.get("Main", "dbHost")
- dbUser = config.get("Main", "dbUser")
- dbPass = config.get("Main", "dbPass")
- dbName = config.get("Main", "dbName")
- lastline = 0
- try:
- # Read state file
- statefile = open(STATEFILE, 'r')
- lastline = int(statefile.readline())
- statefile.close()
- except IOError as e:
- if e.errno != 2:
- raise
- try:
- logfile = open(LOGFILE, 'r')
- except IOError as e:
- if e.errno != 2:
- raise
- print "Log file", LOGFILE, "not found. Exiting!"
- sys.exit(1)
- # Check if the log file was rotated, if so, reset counter
- logfile.seek(0, 2)
- size = logfile.tell()
- if size < lastline:
- lastline = 0
- # Connect to the database...
- conn = MySQLdb.connect (dbHost, dbUser, dbPass, dbName)
- cursor = conn.cursor ()
- logfile.seek(lastline)
- for log in logfile:
- timestamp = datetime.strptime(log[:15], "%b %d %H:%M:%S")
- timestamp = timestamp.replace(year = datetime.now().year)
- fields = log.split()
- if fields[5] == 'bogon' and len(fields) == 8:
- # This is bogon
- cursor.execute("INSERT INTO arpwatch VALUES('%s', %d, '%s', '%s', NULL)" % (normalizemac(fields[7]), ip2int(fields[6]), "bogon", timestamp))
- elif fields[5] == 'new' and len(fields) == 9:
- cursor.execute("INSERT INTO arpwatch VALUES('%s', %d, '%s', '%s', NULL)" % (normalizemac(fields[8]), ip2int(fields[7]), "new", timestamp))
- elif fields[5] == 'flip' and len(fields) == 10:
- cursor.execute("INSERT INTO arpwatch VALUES('%s', %d, '%s', '%s', '%s')" % (normalizemac(fields[8]), ip2int(fields[7]), "flipflop", timestamp, normalizemac(fields[9][1:-1])))
- elif fields[5] == 'Running' and len(fields) == 9:
- pass
- elif fields[5] == 'listening' and len(fields) == 8:
- pass
- elif fields[5] == 'report:' and len(fields) == 9:
- pass
- elif fields[5] == 'short' and len(fields) == 8:
- print "WARNING: ARP request or response received was too short at " + str(timestamp)
- elif fields[5] == 'changed' and len(fields) == 11:
- cursor.execute("INSERT INTO arpwatch VALUES('%s', %d, '%s', '%s', '%s')" % (normalizemac(fields[9]), ip2int(fields[8]), "changed", timestamp, normalizemac(fields[10][1:-1])))
- else:
- print "ERROR: Unrecognized log line: ", log
- lastline = logfile.tell()
- logfile.close()
- cursor.close ()
- conn.close ()
- # Write new state file
- statefile = open(STATEFILE, 'w')
- statefile.write(str(lastline))
- statefile.close()
- if __name__ == '__main__':
- main(sys.argv[1:])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement