#!/usr/bin/env python

import subprocess
import signal
import getopt
import os
import re
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *

global interface
global interface2
global netip

def usage():
	print " "
	print "Clients usage:"
	print " "
	print "-i <interface>    : The interface you want to sniff"
	print "-d <interface>    : The connected interface in to network"
	print " "
	sys.exit()

	return

def ListClients(pkt):
	global netip

	try:
		source_mac = pkt.getlayer(Ether).src
	except:
		return

	try:
		source_ip = pkt.getlayer(IP).src
	except:
		return

	if source_ip == "0.0.0.0":
		return

	if netip != None:
		index = string.find(source_ip, ".")
		srcip = source_ip[0:index]

		if netip != srcip:
			return

	try:
		routegw = subprocess.check_output("route -n | grep -i 'UG' | awk '{{print $2}}'", shell=True).strip()
		if source_ip == routegw:
			return
	except:
		pass

	f1 = open('fclients', 'r')
	f2 = open('fclients', 'a')
	state = 0

	for line in f1:
		space = string.find(line, " ")
		mac = line[0:space]
		space = space + 1
		ip = line[space:len(line) - 1]

		if mac == source_mac and ip == source_ip:
			state = 1
			break
		elif mac == source_mac and ip != source_ip:
			state = 2
			break

	if state == 0:
		print "[   clients][00000000] Added", source_mac, source_ip
		f2.write(source_mac + ' ' + source_ip + '\n')
	elif state == 2:
		f1.close()
		f2.close()

		f1 = open('fclients', 'r')

		try:
			os.remove('fclients.tmp')
		except:
			pass

		f2 = open('fclients.tmp', 'w+')

		for line in f1:
			space = string.find(line, " ")
			mac = line[0:space]

			if mac == source_mac:
				f2.write(source_mac + ' ' + source_ip + '\n')
			else:
				f2.write(line)
	
	f1.close()
	f2.close()

	if state == 2:
		os.rename('fclients.tmp', 'fclients')
	
	return

def SIGNAL_handler(signum, frame):
	global interface
	global interface2

	print "[   clients][00000000] Signal caught."
	print "[   clients][00000000] Sniffing on", interface, "off"
	print "[   clients][00000000] Network on", interface2
	print "[   clients][00000000]", interface, "promisc mode off"
	subprocess.call(['ifconfig', interface, '-promisc'])

	sys.exit()

	return

def main():
	global interface
	global interface2
	global netip

	try:
		opts, args = getopt.getopt(sys.argv[1:],"i:d:")
	except:
		usage()
		sys.exit(1)

	interface = None
	interface2 = None

	for o, a in opts:
		if o == '-i':
			interface = a
		elif o == '-d':
			interface2 = a

	if args or not interface or not interface2:
		usage()
		sys.exit(1)

	retip = None

	try:
            retip = subprocess.check_output("LANG=en_US.utf8 nmcli -t -f IP4 dev list iface '{}' | grep -i IP4.ADDRESS | awk '{{print $3}}' | sed -e 's/\/.*//g'".format(interface2), shell=True)
        except:
            pass

	if retip == None:
		netip = None
	else:
		index = string.find(retip, ".")
		netip = retip[0:index]

	if len(netip) == 0:
		netip = None

	try:
		os.makedirs('/opt/td-config/run/besside/')
	except:
		pass
	
	os.chdir('/opt/td-config/run/besside/')

	f = open('fclients', 'w')
	f.close()

	signal.signal(signal.SIGINT, SIGNAL_handler)
	signal.signal(signal.SIGTERM, SIGNAL_handler)

	print "[   clients][00000000]", interface, "promisc mode on"
	subprocess.call(["ifconfig", interface, 'promisc'])

	print "[   clients][00000000] Sniffing on", interface, "on"
	print "[   clients][00000000] Network on", interface2

	try:
	    sniff(iface=interface, filter="ip", store=0, prn=ListClients)
	except:
	    return

	return

if __name__ == "__main__":
	main()
