#!/usr/bin/env python
#

import subprocess
import os
import sys
import threading
import getopt
import signal
import string
from gi.repository import Gtk, GObject
from struct import *
from socket import *

global ointerface
global lsignal
global qsignal
global minterface
global mdevinterface
global sinterface
global channel
global essid
global bssid

class LinkTest(object):
	builder = None

	def __init__(self):
		global ointerface
		global lsignal
		global qsignal
		global minterface
		global mdevinterface
		global sinterface
		global channel
		global essid 
		global bssid

		self.builder = Gtk.Builder()

		if minterface != 'no':
			self.builder.add_from_file("link_test_niwifi_plus.glade")
		else:
			self.builder.add_from_file("link_test_niwifi.glade")
		self.builder.connect_signals(self)

		self.window = self.builder.get_object("mainWindow")
		self.window.set_title("Link test to wireless network")

		if ointerface == 'wlan0':
			if minterface != 'no':
				self.builder.get_object("label11").set_label(ointerface + ' (Internal 802.11 WiFi device) + 3G modem')
			else:
				self.builder.get_object("label11").set_label(ointerface + ' (Internal 802.11 WiFi device)')
                else:
			if minterface != 'no':
				self.builder.get_object("label11").set_label(ointerface + ' (External 802.11 WiFi device) + 3G modem')
			else:
                        	self.builder.get_object("label11").set_label(ointerface + ' (External 802.11 WiFi device)')

		if ointerface == sinterface:
			self.builder.get_object("label2").set_label('Use the same interface')
			qsignal = lsignal
		else:
			if sinterface == 'wlan0':
				self.builder.get_object("label2").set_label(sinterface + ' (Internal 802.11 WiFi device)')
			else:
				self.builder.get_object("label2").set_label(sinterface + ' (External 802.11 WiFi device)')

		self.builder.get_object("label7").set_label(channel)
		self.builder.get_object("label8").set_label(essid)
		self.builder.get_object("label9").set_label(bssid)
		self.builder.get_object("label6").set_label('Please wait...')

		if minterface != 'no':
			print "[ ltest_gui][00000000] Injecting interface: " + ointerface + " Signal: " + str(lsignal) + " with 3G modem on " + minterface + " with dev: " + mdevinterface + " and Sniffing Interface: " + sinterface + " Signal: " + str(qsignal) + " Channel: " + channel + " Essid: " + essid + " Bssid: " + bssid
		else:
			print "[ ltest_gui][00000000] Injecting interface: " + ointerface + " Signal: " + str(lsignal) + " Sniffing Interface: " + sinterface + " Signal: " + str(qsignal) + " Channel: " + channel + " Essid: " + essid + " Bssid: " + bssid

		self.window.connect("delete-event", Gtk.main_quit)
		self.scroll = self.builder.get_object("mainScrolledWindow")
		self.liststore = self.builder.get_object("liststore1")
		self.treeview = self.builder.get_object("mainTree")

              	renderer_text = Gtk.CellRendererText() 
               	column_text0 = Gtk.TreeViewColumn("Link test", renderer_text, text = 0)
               	self.treeview.append_column(column_text0)

		renderer_text = Gtk.CellRendererPixbuf()
                column_text1 = Gtk.TreeViewColumn('Result', renderer_text, pixbuf = 1)
		self.treeview.append_column(column_text1)

               	self.treeview.show()
		self.scroll.show()
		self.window.show()

		self.testtimeout1 = GObject.timeout_add(100, self.test1, None)
		self.testtimeout2 = GObject.timeout_add(100, self.test2, None)

		if mdevinterface != 'no':
			self.testtimeout3 = GObject.timeout_add(100, self.test3, None)

	def test1(self, *args):
		global ointerface
		global lsignal
		global qsignal
		global minterface
		global mdevinterface
		global sinterface
                global channel
                global essid
                global bssid

	 	self.builder.get_object("button1").set_sensitive(False)
                self.liststore.clear()

		icon_theme = Gtk.IconTheme.get_default()

                test = 'Injecting interface quality signal'
                flag = None

                if int(lsignal) < 70:
                        flag = icon_theme.load_icon('gtk-close', 25, 0)
                else:
                        flag = icon_theme.load_icon('gtk-apply', 25, 0)

                self.liststore.append([test, flag])

                test = 'Sniffing interface quality signal'
                flag = None

                if int(qsignal) < 70:
                        flag = icon_theme.load_icon('gtk-close', 25, 0)
                else:
                        flag = icon_theme.load_icon('gtk-apply', 25, 0)

                self.liststore.append([test, flag])

		subprocess.call('/opt/td-config/bin/airmon-ng stop mon0 >/dev/null', shell=True)
          	subprocess.call("/opt/td-config/bin/airmon-ng start '{}' '{}' >/dev/null".format(sinterface, channel), shell=True)
		subprocess.call("/opt/td-config/bin/aireplay-ng --test -e '{}' -a '{}' mon0 > /opt/td-config/run/link_test/result".format(essid, bssid), shell=True)
		subprocess.call('/opt/td-config/bin/airmon-ng stop mon0 >/dev/null', shell=True)

		ret = subprocess.check_output("grep -i 'Injection is working!' /opt/td-config/run/link_test/result | wc -l", shell=True)
		ret = ret[:len(ret) - 1]

		test = 'Injection test to wireless network'
		flag = None
		if str(ret) == '1':
			flag = icon_theme.load_icon('gtk-apply', 25, 0)	
		else:
			flag = icon_theme.load_icon('gtk-close', 25, 0)

		self.liststore.append([test, flag])

		ret = subprocess.check_output("grep -i '%' /opt/td-config/run/link_test/result | wc -l", shell=True)
		ret = ret[:len(ret) - 1]
		if str(ret) == '0':
			test = 'Connectivity test to wireless network'
			flag = icon_theme.load_icon('gtk-close', 25, 0)
		else:
			test = 'Connectivity test to wireless network'
                        flag = icon_theme.load_icon('gtk-apply', 25, 0)

		self.liststore.append([test, flag])

		test = 'Unique AP ESSID name test'
                flag = None
                rectl = None

                try:
                    retcl = subprocess.check_output("LANG=en_US.utf8 nmcli -t -f SSID dev wifi list iface '{}' | grep -Fi '{}' | wc -l".format(sinterface, essid), shell=True).strip()

                    if len(retcl) == 0:
                        retcl = None
                except:
                    retcl = None

                if retcl == None or retcl != '1':
                        flag = icon_theme.load_icon('gtk-close', 25, 0)
                else:
                        flag = icon_theme.load_icon('gtk-apply', 25, 0)

                self.liststore.append([test, flag])

		return False

	def test2(self, *args):
		global ointerface
		global lsignal
		global qsignal
                global minterface
                global mdevinterface
                global sinterface
                global channel
                global essid
                global bssid

		icon_theme = Gtk.IconTheme.get_default()

                test = 'Injecting interface IP address test'
                flag = None
                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(ointerface), shell=True)
                    if len(retip) == 0:
                        retip = None
                except:
                    retip = None

                if retip == None:
                        flag = icon_theme.load_icon('gtk-close', 25, 0)
                else:
                        flag = icon_theme.load_icon('gtk-apply', 25, 0)

                self.liststore.append([test, flag])

                retcn = '1'

                test = "Internet connectivity test"

                try:
                        retcon = subprocess.check_output("/opt/td-config/scripts/http_conntest.py", shell=True)

                        if string.find(retcon, "Status 1") != -1:
                                retcn = '1'
                                pass
                        else:
                                retcn = '0'
                                pass
                except:
                        retcn = '0'
                        pass

                flag = None

                if retcn != '1':
                        flag = icon_theme.load_icon('gtk-close', 25, 0)
                else:
                        flag = icon_theme.load_icon('gtk-apply', 25, 0)

                self.liststore.append([test, flag])

		if minterface == 'no':
			self.builder.get_object("label6").set_label("")
                        self.builder.get_object("button1").set_sensitive(True)

                return False

	def test3(self, *args):
		global ointerface
		global lsignal
		global qsignal
                global minterface
                global mdevinterface
                global sinterface
                global channel
                global essid
                global bssid

		test = 'Public IP address test for 3G modem'
		icon_theme = Gtk.IconTheme.get_default()
		flag = None

		theip = None

            	try:
                	theip = 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(mdevinterface), shell=True)
                	if len(theip) == 0:
                		flag = icon_theme.load_icon('gtk-close', 25, 0)
				self.liststore.append([test, flag])
				self.builder.get_object("label6").set_label("")
	                        self.builder.get_object("button1").set_sensitive(True)
				return False
            	except:
                	flag = icon_theme.load_icon('gtk-close', 25, 0)
			self.liststore.append([test, flag])
			self.builder.get_object("label6").set_label("")
                        self.builder.get_object("button1").set_sensitive(True)
			return False

            	theip = theip[0:len(theip) - 1]

            	try:
                	inet_pton(AF_INET, theip)
            	except:
                	flag = icon_theme.load_icon('gtk-close', 25, 0)
			self.liststore.append([test, flag])
			self.builder.get_object("label6").set_label("")
                        self.builder.get_object("button1").set_sensitive(True)
			return False

            	f  = unpack('!I', inet_pton(AF_INET, theip))[0]
            	private = ([ 2130706432 , 4278190080 ], [ 3232235520 , 4294901760 ], [ 2886729728 , 4293918720 ], [ 167772160 , 4278190080 ])

            	ispriv = False

            	for net in private:
               		if (f & net[1] == net[0]):
                    		ispriv = True

            	if ispriv == True:
                	flag = icon_theme.load_icon('gtk-close', 25, 0)
		else:
			flag = icon_theme.load_icon('gtk-apply', 25, 0)

		self.liststore.append([test, flag])

		self.builder.get_object("label6").set_label("")
                self.builder.get_object("button1").set_sensitive(True)

		return False

	def repeat(self, *args):
		try:
	                subprocess.call('rm -Rf /opt/td-config/run/link_test 2> /dev/null', shell=True)
	        except:
	                pass

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

		self.builder.get_object("label6").set_label("")
                self.builder.get_object("label6").set_label('Please wait...')
		self.liststore.clear()
		self.builder.get_object("button1").set_sensitive(False)

		self.testtimeout1 = GObject.timeout_add(100, self.test1, None)
		self.testtimeout2 = GObject.timeout_add(100, self.test2, None)

		if mdevinterface != 'no':
			self.testtimeout3 = GObject.timeout_add(100, self.test3, None)

def usage():
        print " "
        print "  Wireless Link Test (GUI) usage:"
        print " "
	print "  -o <Interface>   : The injecting network interface"
	print "  -l <Signal>      : The injecting network interface signal"
	print "  -m <Interface|no>: 3G modem network interface or disable"
	print "  -p <profile|no>  : 3G modem network profile or disable"
	print "  -i <Interface>   : The sniffing network interface"
	print "  -q <Signal>      : The sniffing network interface signal"
	print "  -c <Channel>     : The channel of ESSID/BSSID network"
	print "  -e <ESSID>       : The ESSID of your wireless network"
	print "  -b <BSSID>       : The BSSID of your wireless network"
        print " "
        sys.exit()

        return

def signal_handler(signum, frame):
        print "[ ltest_gui][00000000] Signal caught."
        sys.exit()

        return

def main():
	global ointerface
	global lsignal
	global qsignal
	global minterface
	global mdevinterface
	global sinterface
	global channel
	global essid
	global bssid

        try:
                opts, args = getopt.getopt(sys.argv[1:],"o:l:m:p:i:q:c:e:b:")
        except:
                usage()
                sys.exit(1)

	ointerface = None
	minterface = None
	mdevinterface = None
	sinterface = None
	channel = None
        essid = None
	bssid = None

        for o, a in opts:
		if o == '-o':
			ointerface = a
		elif o == '-l':
			lsignal = a
		elif o == '-m':
			mdevinterface = a
		elif o == '-p':
			minterface = a
                elif o == '-i':
			sinterface = a
		elif o == '-q':
			qsignal = a
		elif o == '-c':
			channel = a
		elif o == '-e':
                        essid = a
		elif o == '-b':
			bssid = a

        if ointerface == None or mdevinterface == None or minterface == None or sinterface == None or channel == None or essid == None or bssid == None:
                usage()
                sys.exit(1)

	try:
                subprocess.call('rm -Rf /opt/td-config/run/link_test 2> /dev/null', shell=True)
        except:
                pass

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

	bssid = bssid.upper()

        signal.signal(signal.SIGINT, signal_handler)
        signal.signal(signal.SIGTERM, signal_handler)

	app = LinkTest()
	Gtk.main()

	return

if __name__ == "__main__":
	main()
