From 339361dc6560731bc5f7bbded7ac2f378c92d12d Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Tue, 15 Aug 2017 21:44:12 +0500 Subject: [PATCH 01/11] Fixed Configure argument parsing for router auth --- ptcl.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ptcl.py b/ptcl.py index 24e308d..5564080 100755 --- a/ptcl.py +++ b/ptcl.py @@ -24,7 +24,7 @@ def main(): parser.add_argument('-r', '--restart', help="Restart Router.", action='store_true') parser.add_argument('-sd', '--show-dhcp', help='Show DHCP Info.', action='store_true') parser.add_argument('-s', '--show-active', help='Show Active Devices.', default='.') - parser.add_argument('-c', '--configure', help='Configure router settings.') + parser.add_argument('-c', '--configure', help='Configure router settings.', action='store_true') parser.add_argument('-q', '--quiet', help='Quite mode.', nargs='?', default='True') args = parser.parse_args() # print args @@ -71,14 +71,18 @@ def main(): elif args.configure: # Creating a config file + DEFAULT = {'mask': '192.168.1.1', 'username': 'admin', 'password': 'admin'} mask = raw_input("Please enter router gateway: \t\t# Default 192.168.1.1") + if mask: + DEFAULT['mask'] = mask username = raw_input("Please enter username of your router page: \t\t# Default 'admin'") + if username: + DEFAULT['username'] = username password = raw_input("Please enter password of your router page: \t\t# Default 'admin'") - config['Router-Auth'] = { - 'mask': '192.168.1.1', - 'username': 'admin', - 'password': 'admin' - } + if password: + DEFAULT['password'] = password + config['Router-Auth'] = DEFAULT + with open('config.ini', 'w') as configfile: config.write(configfile) From 9cc9de7400820acf049cec7ba953af90340f4cc9 Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Tue, 15 Aug 2017 21:48:18 +0500 Subject: [PATCH 02/11] Arranged. --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 62871bf..f434174 100755 --- a/README.md +++ b/README.md @@ -47,21 +47,21 @@ A PTCL-Router API. - [ ] Parsing router logs. - [ ] Obtaining Pin-Code of the router and changing it. - [ ] Displaying current password of the SSID. -- [ ] Changin router username and password from the command-line. +- [ ] Changing router username and password from the command-line. - [ ] Changing SSID-Name. - [ ] Adding a method to change router password. +- [ ] Add CLI MODE for unblocking devices. - [ ] Option to change frequency 2.4 Ghz or 5 Ghz. - [ ] Option to change router transmission power. - [ ] Improving display for blocked devices. -- [ ] Exclude android devices from station info and dhcp info. +- [ ] Exclude android devices from station info and dhcp info (Optional). - [ ] Time restriction for user (by specifying or choosing from station info) device mac address or hostname. - [ ] Adding URL to block unnecessary use for a website, also time limit for a site usage. - [ ] Monitor devices connection info i.e., when they connect to the router and disconnect. Also devices uptime of the day. - [ ] Block devices who remain connected to the router for x time (6 hours). Unblock them after 6 hours. - [ ] Searching suspected users in the station info (Currently Active Devices) when speed is slow. - [ ] Getting device connection info in a nice CSV file. -- [ ] Uploading CSV on a cloud everyday. -- [ ] Add CLI MODE for unblocking devices +- [ ] Uploading CSV on cloud everyday. - [X] Setting up custom hostname for specific device (mac address). - [X] Optimize Regular Expressions. - [X] CLI MODE and SILENT MODE for blocking devices. From 86477199f6a2e541e0f63f6f27bde2c12fb173f6 Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Fri, 18 Aug 2017 12:29:19 +0500 Subject: [PATCH 03/11] Fixed hostname duplication disappearance from dictionary (data structure) by using Tuple --- config.ini | 5 +++++ ptcl.py | 6 +++--- router.py | 8 ++++---- 3 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 config.ini diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..5c74e4d --- /dev/null +++ b/config.ini @@ -0,0 +1,5 @@ +[User-Aliases] +[Router-Auth] +username = admin +password = admin +mask = 192.168.1.1 diff --git a/ptcl.py b/ptcl.py index 5564080..a188ed8 100755 --- a/ptcl.py +++ b/ptcl.py @@ -13,7 +13,7 @@ # "asad": "A0:32:99:AB:33:31", # "hhp": "44-1C-A8-73-A3-17" # } -config[User-Aliases] = {} +config['User-Aliases'] = {} def main(): parser = argparse.ArgumentParser(description="Control PTCL router from command-line.") @@ -82,9 +82,9 @@ def main(): if password: DEFAULT['password'] = password config['Router-Auth'] = DEFAULT - + print DEFAULT with open('config.ini', 'w') as configfile: - config.write(configfile) + config.write(DEFAULT) elif args.show_active == '.': # print "Calling show_active Function" diff --git a/router.py b/router.py index efe93a1..2943278 100755 --- a/router.py +++ b/router.py @@ -102,11 +102,11 @@ def show_active_dev(self): ''' self.get_stationinfo() self.get_dhcpinfo() - self.mac_and_host = dict(zip(self.dev_hostname, self.mac_address)) + self.mac_and_host = tuple(zip(self.dev_hostname, self.mac_address)) hostnames = [] print "-" * 20 + "STATION-INFO" + "-" * 20 + '\n' count = 1 - for k, v in self.mac_and_host.iteritems(): + for k, v in self.mac_and_host: for active_clients in self.active_dev: if active_clients in v: print "(%s) %s%s\n" % (count, k + ":" + ' ' * (30 - len(k) - len(str(count))), active_clients.upper()) @@ -140,7 +140,7 @@ def show_blocked_dev(self): if not i.find("input"): if Router.mac_adr_regex.search(i.text): print i.text + '\n' - + def set_hostname(self, custom_name, mac_address): ''' @@ -154,7 +154,7 @@ def set_hostname(self, custom_name, mac_address): if mac_address in i: del(self.mac_and_host[i[0]]) self.mac_and_host[custom_name] = mac_address - + def reboot_router(self): ''' From dfc1d32c15fa0b1b3d49da81730398545f3e94a1 Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Fri, 18 Aug 2017 12:54:05 +0500 Subject: [PATCH 04/11] 'Configuration --- config.ini | 4 ++-- ptcl.py | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/config.ini b/config.ini index 5c74e4d..c32d5d0 100644 --- a/config.ini +++ b/config.ini @@ -1,5 +1,5 @@ [User-Aliases] [Router-Auth] username = admin -password = admin -mask = 192.168.1.1 +password = bec10 +mask = 192.168.1.10 diff --git a/ptcl.py b/ptcl.py index a188ed8..20f01c6 100755 --- a/ptcl.py +++ b/ptcl.py @@ -3,7 +3,7 @@ import sys import configobj -config = configobj.ConfigObj() + ptcl = Router() # ptcl = Router(mask='192.168.10.1', password='bec10') # Defining custom aliases @@ -13,7 +13,6 @@ # "asad": "A0:32:99:AB:33:31", # "hhp": "44-1C-A8-73-A3-17" # } -config['User-Aliases'] = {} def main(): parser = argparse.ArgumentParser(description="Control PTCL router from command-line.") @@ -25,6 +24,7 @@ def main(): parser.add_argument('-sd', '--show-dhcp', help='Show DHCP Info.', action='store_true') parser.add_argument('-s', '--show-active', help='Show Active Devices.', default='.') parser.add_argument('-c', '--configure', help='Configure router settings.', action='store_true') + parser.add_argument('-sa', '--set-alias', help='Set custom alias for a device hostname.', action='store_true') parser.add_argument('-q', '--quiet', help='Quite mode.', nargs='?', default='True') args = parser.parse_args() # print args @@ -71,20 +71,25 @@ def main(): elif args.configure: # Creating a config file + config = configobj.ConfigObj() + config['User-Aliases'] = {} DEFAULT = {'mask': '192.168.1.1', 'username': 'admin', 'password': 'admin'} - mask = raw_input("Please enter router gateway: \t\t# Default 192.168.1.1") + mask = raw_input("Leave empty for default configuration.\nPlease enter router gateway\t(Default 192.168.1.1)\t: ") if mask: DEFAULT['mask'] = mask - username = raw_input("Please enter username of your router page: \t\t# Default 'admin'") + username = raw_input("Please enter router username\t(Default admin)\t: ") if username: DEFAULT['username'] = username - password = raw_input("Please enter password of your router page: \t\t# Default 'admin'") + password = raw_input("Please enter router password\t(Default admin)\t: ") if password: DEFAULT['password'] = password config['Router-Auth'] = DEFAULT - print DEFAULT with open('config.ini', 'w') as configfile: - config.write(DEFAULT) + config.write(configfile) + print '\nConfiguration file Generated.' + + elif args.set_alias: + pass elif args.show_active == '.': # print "Calling show_active Function" From 014431d175dbe9d653d0677d4627e633255e6859 Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Wed, 30 Aug 2017 21:38:26 +0500 Subject: [PATCH 05/11] Fixed args --- ptcl.py | 12 ++++++------ router.py | 21 ++++++++++++++------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/ptcl.py b/ptcl.py index 20f01c6..5410456 100755 --- a/ptcl.py +++ b/ptcl.py @@ -4,8 +4,8 @@ import configobj -ptcl = Router() -# ptcl = Router(mask='192.168.10.1', password='bec10') +# ptcl = Router() +ptcl = Router(mask='192.168.10.1', password='') # Defining custom aliases # config['User-Aliases'] = { # "mytab": "5c:2e:59:4d:33:67", @@ -23,13 +23,13 @@ def main(): parser.add_argument('-r', '--restart', help="Restart Router.", action='store_true') parser.add_argument('-sd', '--show-dhcp', help='Show DHCP Info.', action='store_true') parser.add_argument('-s', '--show-active', help='Show Active Devices.', default='.') - parser.add_argument('-c', '--configure', help='Configure router settings.', action='store_true') + parser.add_argument('--configure', help='Configure router settings.', action='store_true') parser.add_argument('-sa', '--set-alias', help='Set custom alias for a device hostname.', action='store_true') - parser.add_argument('-q', '--quiet', help='Quite mode.', nargs='?', default='True') + parser.add_argument('-c', '--cli', help='Silent mode.', nargs='?', default='False') args = parser.parse_args() # print args - if args.quiet == 'True': + if args.cli == 'False': if args.block: # print "Calling blocker Function" ptcl.get_sessionkey() @@ -99,7 +99,7 @@ def main(): print "Invalid Argument" - elif not args.quiet: + elif not args.cli: if not args.block: # print "Calling blocker function - CLI MODE." name = ptcl.show_active_dev() diff --git a/router.py b/router.py index 2943278..a7d9049 100755 --- a/router.py +++ b/router.py @@ -57,7 +57,9 @@ def get_sessionkey(self): def get_dhcpinfo(self): - '''Gets information from dhcp i.e., Mac Adresses and Hostnames.''' + ''' + Gets information from dhcp i.e., Mac Adresses and Hostnames. + ''' r, soup = self.scrape_page(self.mask + 'dhcpinfo.html') count = 1 td = soup.findAll('td') @@ -76,7 +78,9 @@ def get_dhcpinfo(self): def show_dhcpinfo(self): - '''Shows DHCP information.''' + ''' + Shows DHCP information. + ''' self.get_dhcpinfo() print "-" * 20 + "DHCP-INFO" + "-" * 20 + '\n' for num, i in enumerate(zip(self.dev_hostname, self.mac_address), 1): @@ -95,7 +99,6 @@ def get_stationinfo(self): if self.mac_adr_regex.search(i.text.strip()): self.active_dev.append(i.text.strip().lower().encode('ascii')) - def show_active_dev(self): ''' Shows active devices (Mac Addresses) and their hostnames. @@ -207,12 +210,16 @@ def get_suspects(self): def monitor_dev(self): # Monitor Devices - '''Monitor devices, when they connect to router and disconnect. Also - gets the time a device remains connected to the router.''' + ''' + Monitor devices, when they connect to router and disconnect. Also + gets the time a device remains connected to the router. + ''' pass def dev_conninfo(self): # Device Connection Info - '''Analyzes how much time a device remains connected to the device throughout - the day.''' + ''' + Analyzes how much time a device remains connected to the device throughout + the day. + ''' pass From bde20e9210f7f074bb1798b3dba30e0c130e6752 Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Wed, 30 Aug 2017 23:34:37 +0500 Subject: [PATCH 06/11] Fixed silent mode --- ptcl.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ptcl.py b/ptcl.py index 5410456..c73e694 100755 --- a/ptcl.py +++ b/ptcl.py @@ -4,8 +4,14 @@ import configobj -# ptcl = Router() -ptcl = Router(mask='192.168.10.1', password='') +ptcl = Router(password='ptcl') +my_macs = {"mytab": "5c:2e:59:4d:33:67", +"ahmer": "68:94:23:AC:59:51", +"asad": "A0:32:99:AB:33:31", +"hhp": "44-1C-A8-73-A3-17", +"haris": "64:5A:04:76:C7:9C" +} +# ptcl = Router(mask='192.168.10.1', password='123motorcross') # Defining custom aliases # config['User-Aliases'] = { # "mytab": "5c:2e:59:4d:33:67", @@ -18,7 +24,7 @@ def main(): parser = argparse.ArgumentParser(description="Control PTCL router from command-line.") parser.add_argument('-b', '--block', help="Block device.", nargs='?') parser.add_argument('-sb', '--blocked_dev', help='Display blocked devices.', action='store_true') - parser.add_argument('-u', '--unblock', help="Unblock device.", nargs='?') + parser.add_argument('-ub', '--unblock', help="Unblock device.", nargs='?') parser.add_argument('-a', '--active-devices', help="Gets number of devices connected to the router.", action='store_true') parser.add_argument('-r', '--restart', help="Restart Router.", action='store_true') parser.add_argument('-sd', '--show-dhcp', help='Show DHCP Info.', action='store_true') @@ -100,9 +106,11 @@ def main(): elif not args.cli: + ptcl.get_sessionkey() if not args.block: # print "Calling blocker function - CLI MODE." name = ptcl.show_active_dev() + ptcl.mac_and_host = dict(ptcl.mac_and_host) dev_mac = int(raw_input("Please Enter Device Number: ")) - 1 ptcl.block_dev(ptcl.mac_and_host[name[dev_mac]]) print "%s has been blocked." % name[dev_mac].capitalize() @@ -111,6 +119,7 @@ def main(): elif not args.unblock: # print "Calling unblocker function - CLI MODE." name = ptcl.show_active_dev() + ptcl.mac_and_host = dict(ptcl.mac_and_host) dev_mac = int(raw_input("Please Enter Device Number: ")) - 1 ptcl.unblock_dev(ptcl.mac_and_host[name[dev_mac]]) print "%s has been unblocked." % name[dev_mac].capitalize() From cb3c198ea5c4fc84b5c44fdd6a3ada82cbdfea35 Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Thu, 31 Aug 2017 20:23:08 +0500 Subject: [PATCH 07/11] Updated Show DHCPINFO - Display --- ptcl.py | 4 ++-- router.py | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ptcl.py b/ptcl.py index c73e694..0fccdb7 100755 --- a/ptcl.py +++ b/ptcl.py @@ -4,14 +4,14 @@ import configobj -ptcl = Router(password='ptcl') +# ptcl = Router(password='ptcl') my_macs = {"mytab": "5c:2e:59:4d:33:67", "ahmer": "68:94:23:AC:59:51", "asad": "A0:32:99:AB:33:31", "hhp": "44-1C-A8-73-A3-17", "haris": "64:5A:04:76:C7:9C" } -# ptcl = Router(mask='192.168.10.1', password='123motorcross') +ptcl = Router(mask='192.168.10.1', password='123motorcross') # Defining custom aliases # config['User-Aliases'] = { # "mytab": "5c:2e:59:4d:33:67", diff --git a/router.py b/router.py index a7d9049..d48c883 100755 --- a/router.py +++ b/router.py @@ -13,7 +13,7 @@ import bs4 import re import sys - +from tabulate import tabulate class Router(object): ''' @@ -41,6 +41,8 @@ def scrape_page(self, url): ''' try: request_url = self.session.get(url) + if request_url.status_code == 401: + sys.exit("Username or Password is incorrect.") html_soup = bs4.BeautifulSoup(request_url.content, 'html.parser') return request_url, html_soup except requests.exceptions.ConnectionError: @@ -82,11 +84,8 @@ def show_dhcpinfo(self): Shows DHCP information. ''' self.get_dhcpinfo() - print "-" * 20 + "DHCP-INFO" + "-" * 20 + '\n' - for num, i in enumerate(zip(self.dev_hostname, self.mac_address), 1): - whitespace = 30 - len(i[0]) - len(str(num)) - print "(%s) %s:%s\n" % (num, i[0], ' ' * whitespace + i[1].upper()) - print "-" * 49 + print tabulate({"HOSTNAME": self.dev_hostname, "MAC-ADDRESSES": self.mac_address}, headers=['HOSTNAME', 'Device-No.', 'MAC-ADDRESSES'], tablefmt='fancy_grid') + print "\n\n\t\tTotal Active Devices are [%s].\n\n" % len(self.dev_hostname) def get_stationinfo(self): From 80c09901562a3a8a471ed871c645d3f8a2eaad8f Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Fri, 1 Sep 2017 14:34:33 +0500 Subject: [PATCH 08/11] Improved Display --- ptcl.py | 11 ++++------- router.py | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/ptcl.py b/ptcl.py index 0fccdb7..e0f8ec7 100755 --- a/ptcl.py +++ b/ptcl.py @@ -110,22 +110,19 @@ def main(): if not args.block: # print "Calling blocker function - CLI MODE." name = ptcl.show_active_dev() - ptcl.mac_and_host = dict(ptcl.mac_and_host) + ptcl.host_and_mac = dict(ptcl.host_and_mac) dev_mac = int(raw_input("Please Enter Device Number: ")) - 1 - ptcl.block_dev(ptcl.mac_and_host[name[dev_mac]]) + ptcl.block_dev(ptcl.host_and_mac[name[dev_mac]]) print "%s has been blocked." % name[dev_mac].capitalize() elif not args.unblock: # print "Calling unblocker function - CLI MODE." name = ptcl.show_active_dev() - ptcl.mac_and_host = dict(ptcl.mac_and_host) + ptcl.host_and_mac = dict(ptcl.host_and_mac) dev_mac = int(raw_input("Please Enter Device Number: ")) - 1 - ptcl.unblock_dev(ptcl.mac_and_host[name[dev_mac]]) + ptcl.unblock_dev(ptcl.host_and_mac[name[dev_mac]]) print "%s has been unblocked." % name[dev_mac].capitalize() -import time -start_time = time.time() main() -print("--- %s seconds ---" % (time.time() - start_time)) diff --git a/router.py b/router.py index d48c883..4042cfc 100755 --- a/router.py +++ b/router.py @@ -29,7 +29,7 @@ def __init__(self, mask="192.168.1.1", username="admin", password="admin"): self.dev_hostname = [] # Devices Hostname self.mac_address = [] # Devices Mac Address self.active_dev = [] # Active Devices on Wi-Fi - self.mac_and_host = {} # Mac Addresses and Hostnames + self.host_and_mac = {} # Mac Addresses and Hostnames self.session = requests.Session() self.session.auth = (self.username, self.password) self.session_key = "" @@ -84,8 +84,8 @@ def show_dhcpinfo(self): Shows DHCP information. ''' self.get_dhcpinfo() - print tabulate({"HOSTNAME": self.dev_hostname, "MAC-ADDRESSES": self.mac_address}, headers=['HOSTNAME', 'Device-No.', 'MAC-ADDRESSES'], tablefmt='fancy_grid') - print "\n\n\t\tTotal Active Devices are [%s].\n\n" % len(self.dev_hostname) + print tabulate({"HOSTNAME": self.dev_hostname, "MAC-ADDRESSES": self.mac_address}, headers=['HOSTNAME', 'MAC-ADDRESSES'], tablefmt='fancy_grid') + print "\n\n\t\tTotal Devices Connected Today are: [%s].\n\n" % len(self.dev_hostname) def get_stationinfo(self): @@ -104,17 +104,17 @@ def show_active_dev(self): ''' self.get_stationinfo() self.get_dhcpinfo() - self.mac_and_host = tuple(zip(self.dev_hostname, self.mac_address)) + self.host_and_mac = tuple(zip(self.dev_hostname, self.mac_address)) hostnames = [] - print "-" * 20 + "STATION-INFO" + "-" * 20 + '\n' + display_list = [] count = 1 - for k, v in self.mac_and_host: + for hostname, mac in self.host_and_mac: for active_clients in self.active_dev: - if active_clients in v: - print "(%s) %s%s\n" % (count, k + ":" + ' ' * (30 - len(k) - len(str(count))), active_clients.upper()) - hostnames.append(k) + if active_clients in mac: + display_list.append([count, hostname, active_clients]) + hostnames.append(hostname) count += 1 - print "-" * 52 + '\n' + print tabulate(display_list, headers=["DEVICE-NO.", "HOSTNAME", "MAC"], tablefmt="fancy_grid") return hostnames @@ -151,11 +151,11 @@ def set_hostname(self, custom_name, mac_address): ''' self.get_dhcpinfo() custom_hostnames = {} - self.mac_and_host = dict(zip(self.dev_hostname, self.mac_address)) - for i in self.mac_and_host.items(): + self.host_and_mac = dict(zip(self.dev_hostname, self.mac_address)) + for i in self.host_and_mac.items(): if mac_address in i: - del(self.mac_and_host[i[0]]) - self.mac_and_host[custom_name] = mac_address + del(self.host_and_mac[i[0]]) + self.host_and_mac[custom_name] = mac_address def reboot_router(self): From 070d5aee0307d31e8f9ccf82cc47dea4102a4821 Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Fri, 1 Sep 2017 23:18:18 +0500 Subject: [PATCH 09/11] Improved Display, Configuration --- config.ini | 5 ----- configure.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) delete mode 100644 config.ini create mode 100644 configure.py diff --git a/config.ini b/config.ini deleted file mode 100644 index c32d5d0..0000000 --- a/config.ini +++ /dev/null @@ -1,5 +0,0 @@ -[User-Aliases] -[Router-Auth] -username = admin -password = bec10 -mask = 192.168.1.10 diff --git a/configure.py b/configure.py new file mode 100644 index 0000000..60b00b3 --- /dev/null +++ b/configure.py @@ -0,0 +1,62 @@ +import configobj +import os + + +def write_config(): + # Creating a config file + try: + os.chdir(os.path.expanduser(os.path.join('~', ''))) + os.makedirs('.config' + os.sep + "ptcl") + os.chdir('.config' + os.sep + "ptcl") + + except OSError: + # If already exists + pass + + config = configobj.ConfigObj() + DEFAULT = {'mask': '192.168.1.1', 'username': 'admin', 'password': 'admin'} + mask = raw_input("Leave empty for default configuration.\nPlease enter router gateway\t(Default 192.168.1.1)\t: ") + + if mask: + DEFAULT['mask'] = mask + username = raw_input("Please enter router username\t(Default admin)\t: ") + + if username: + DEFAULT['username'] = username + password = raw_input("Please enter router password\t(Default admin)\t: ") + + if password: + DEFAULT['password'] = password + config['Router-Auth'] = DEFAULT + config['Aliases'] = {} + + with open('config.ini', 'w') as configfile: + config.write(configfile) + print '\nConfiguration file Generated.' + + +def set_alias(): + # Defining custom aliases + config = configobj.ConfigObj('config.ini') + + while True: + hostname = raw_input("Set Alias for hosname: ") + if hostname == 'q': + break + macaddress= raw_input("Enter it\'s macaddress: ") + + if macaddress == 'q': + break + + else: + if hostname not in config["Aliases"]: + config["Aliases"][hostname] = macaddress + with open('config.ini', 'r+') as configfile: + config.write(configfile) + else: + print "Already Present." + +def get_alias(): + # Return Aliases + config = configobj.ConfigObj('config.ini') + return config["Aliases"] From d72fd1c3e316e1c79256e683cabf8e2dab62c17d Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Fri, 1 Sep 2017 23:22:25 +0500 Subject: [PATCH 10/11] Updated --- config.ini | 5 --- configure.py | 62 ++++++++++++++++++++++++++ ptcl.py | 120 +++++++++++++++++++++++++++++++-------------------- router.py | 24 +++-------- 4 files changed, 142 insertions(+), 69 deletions(-) delete mode 100644 config.ini create mode 100644 configure.py diff --git a/config.ini b/config.ini deleted file mode 100644 index c32d5d0..0000000 --- a/config.ini +++ /dev/null @@ -1,5 +0,0 @@ -[User-Aliases] -[Router-Auth] -username = admin -password = bec10 -mask = 192.168.1.10 diff --git a/configure.py b/configure.py new file mode 100644 index 0000000..60b00b3 --- /dev/null +++ b/configure.py @@ -0,0 +1,62 @@ +import configobj +import os + + +def write_config(): + # Creating a config file + try: + os.chdir(os.path.expanduser(os.path.join('~', ''))) + os.makedirs('.config' + os.sep + "ptcl") + os.chdir('.config' + os.sep + "ptcl") + + except OSError: + # If already exists + pass + + config = configobj.ConfigObj() + DEFAULT = {'mask': '192.168.1.1', 'username': 'admin', 'password': 'admin'} + mask = raw_input("Leave empty for default configuration.\nPlease enter router gateway\t(Default 192.168.1.1)\t: ") + + if mask: + DEFAULT['mask'] = mask + username = raw_input("Please enter router username\t(Default admin)\t: ") + + if username: + DEFAULT['username'] = username + password = raw_input("Please enter router password\t(Default admin)\t: ") + + if password: + DEFAULT['password'] = password + config['Router-Auth'] = DEFAULT + config['Aliases'] = {} + + with open('config.ini', 'w') as configfile: + config.write(configfile) + print '\nConfiguration file Generated.' + + +def set_alias(): + # Defining custom aliases + config = configobj.ConfigObj('config.ini') + + while True: + hostname = raw_input("Set Alias for hosname: ") + if hostname == 'q': + break + macaddress= raw_input("Enter it\'s macaddress: ") + + if macaddress == 'q': + break + + else: + if hostname not in config["Aliases"]: + config["Aliases"][hostname] = macaddress + with open('config.ini', 'r+') as configfile: + config.write(configfile) + else: + print "Already Present." + +def get_alias(): + # Return Aliases + config = configobj.ConfigObj('config.ini') + return config["Aliases"] diff --git a/ptcl.py b/ptcl.py index e0f8ec7..1ac0b2c 100755 --- a/ptcl.py +++ b/ptcl.py @@ -2,24 +2,69 @@ import argparse import sys import configobj +import configure +import os +from tabulate import tabulate + +path = os.path.expanduser(os.path.join('~', '.config' + os.sep + 'ptcl')) + +if os.path.exists(path): + os.chdir(path) + config = configobj.ConfigObj('config.ini') + ptcl = Router(mask=config["Router-Auth"]["mask"], password=config["Router-Auth"]["password"]) + +else: + print "Configuration file doesn't exists. Run it with --configure parameter.\nExecuting Fallback mode." + ptcl = Router(mask="192.168.10.1", password="123motorcross") + # ptcl = Router(password='ptcl') + + +def show_dhcpinfo(): + ''' + Shows DHCP information. + ''' + ptcl.get_dhcpinfo() + print tabulate({"HOSTNAME": ptcl.dev_hostname, "MAC-ADDRESSES": ptcl.mac_address}, headers=['HOSTNAME', 'MAC-ADDRESSES'], tablefmt='fancy_grid') + print "\n\n\t\tTotal Devices Connected Today are: [%s].\n\n" % len(ptcl.dev_hostname) + + +def show_active_dev(): + ''' + Shows active devices (Mac Addresses) and their hostnames. + ''' + ptcl.get_stationinfo() + ptcl.get_dhcpinfo() + ptcl.host_and_mac = tuple(zip(ptcl.dev_hostname, ptcl.mac_address)) + hostnames = [] + display_list = [] + aliases = configure.get_alias() + count = 1 + print "\nShowing Currently Active Devices.\n" + for hostname, mac in ptcl.host_and_mac: + for active_clients in ptcl.active_dev: + if active_clients in mac: + if mac in aliases.itervalues(): + display_list.append([count, aliases.keys()[aliases.values().index(mac)], active_clients]) + else: + display_list.append([count, hostname, active_clients]) + hostnames.append(hostname) + count += 1 + print tabulate(display_list, headers=["DEVICE-NO.", "HOSTNAME", "MAC"], tablefmt="fancy_grid") + return hostnames + + +def show_blocked_dev(): + ''' + Display blocked devices. + ''' + r, soup = ptcl.scrape_page(ptcl.mask + "wlmacflt.cmd?action=view") + print "Showing blocked devices.\n" + for i in soup.findAll('td'): + if not i.find("input"): + if Router.mac_adr_regex.search(i.text): + print i.text + '\n' -# ptcl = Router(password='ptcl') -my_macs = {"mytab": "5c:2e:59:4d:33:67", -"ahmer": "68:94:23:AC:59:51", -"asad": "A0:32:99:AB:33:31", -"hhp": "44-1C-A8-73-A3-17", -"haris": "64:5A:04:76:C7:9C" -} -ptcl = Router(mask='192.168.10.1', password='123motorcross') -# Defining custom aliases -# config['User-Aliases'] = { -# "mytab": "5c:2e:59:4d:33:67", -# "ahmer": "68:94:23:AC:59:51", -# "asad": "A0:32:99:AB:33:31", -# "hhp": "44-1C-A8-73-A3-17" -# } - def main(): parser = argparse.ArgumentParser(description="Control PTCL router from command-line.") parser.add_argument('-b', '--block', help="Block device.", nargs='?') @@ -36,9 +81,10 @@ def main(): # print args if args.cli == 'False': + my_macs = configure.get_alias() if args.block: # print "Calling blocker Function" - ptcl.get_sessionkey() + ptcl.key() if args.block in my_macs.iterkeys(): # print "Calling blocker function - AUTOMATED MODE." ptcl.block_dev(my_macs[args.block.lower()]) @@ -49,7 +95,6 @@ def main(): print "User not found." elif args.unblock: - ptcl.get_sessionkey() if args.unblock in my_macs.iterkeys(): # print "Calling unblocker function - AUTOMATED MODE" ptcl.unblock_dev(my_macs[args.unblock.lower()]) @@ -64,52 +109,34 @@ def main(): elif args.restart: # print "Calling restart Function" - ptcl.get_sessionkey() ptcl.reboot_router() elif args.show_dhcp: # print "Calling DHCP_info Function" - # ptcl.get_sessionkey() - ptcl.show_dhcpinfo() + show_dhcpinfo() elif args.blocked_dev: - ptcl.show_blocked_dev() + show_blocked_dev() elif args.configure: - # Creating a config file - config = configobj.ConfigObj() - config['User-Aliases'] = {} - DEFAULT = {'mask': '192.168.1.1', 'username': 'admin', 'password': 'admin'} - mask = raw_input("Leave empty for default configuration.\nPlease enter router gateway\t(Default 192.168.1.1)\t: ") - if mask: - DEFAULT['mask'] = mask - username = raw_input("Please enter router username\t(Default admin)\t: ") - if username: - DEFAULT['username'] = username - password = raw_input("Please enter router password\t(Default admin)\t: ") - if password: - DEFAULT['password'] = password - config['Router-Auth'] = DEFAULT - with open('config.ini', 'w') as configfile: - config.write(configfile) - print '\nConfiguration file Generated.' + configure.write_config() elif args.set_alias: - pass + show_active_dev() + configure.set_alias() elif args.show_active == '.': # print "Calling show_active Function" - ptcl.show_active_dev() + show_active_dev() else: print "Invalid Argument" elif not args.cli: - ptcl.get_sessionkey() if not args.block: # print "Calling blocker function - CLI MODE." - name = ptcl.show_active_dev() + name = show_active_dev() ptcl.host_and_mac = dict(ptcl.host_and_mac) dev_mac = int(raw_input("Please Enter Device Number: ")) - 1 ptcl.block_dev(ptcl.host_and_mac[name[dev_mac]]) @@ -118,10 +145,11 @@ def main(): elif not args.unblock: # print "Calling unblocker function - CLI MODE." - name = ptcl.show_active_dev() + name = show_active_dev() ptcl.host_and_mac = dict(ptcl.host_and_mac) - dev_mac = int(raw_input("Please Enter Device Number: ")) - 1 - ptcl.unblock_dev(ptcl.host_and_mac[name[dev_mac]]) + dev_mac = raw_input("Please enter device mac address: ") + ptcl.unblock_dev(dev_mac) + # ptcl.unblock_dev(ptcl.host_and_mac[name[dev_mac]]) print "%s has been unblocked." % name[dev_mac].capitalize() diff --git a/router.py b/router.py index 4042cfc..01bd65f 100755 --- a/router.py +++ b/router.py @@ -29,7 +29,7 @@ def __init__(self, mask="192.168.1.1", username="admin", password="admin"): self.dev_hostname = [] # Devices Hostname self.mac_address = [] # Devices Mac Address self.active_dev = [] # Active Devices on Wi-Fi - self.host_and_mac = {} # Mac Addresses and Hostnames + self.host_and_mac = [] # Mac Addresses and Hostnames self.session = requests.Session() self.session.auth = (self.username, self.password) self.session_key = "" @@ -46,7 +46,7 @@ def scrape_page(self, url): html_soup = bs4.BeautifulSoup(request_url.content, 'html.parser') return request_url, html_soup except requests.exceptions.ConnectionError: - print "Internet Connection Down.\nExiting..." + print("Internet Connection Down.\nExiting...") sys.exit() @@ -55,7 +55,8 @@ def get_sessionkey(self): Gets session key from the html page. ''' r, soup = self.scrape_page(self.mask + "wlmacflt.cmd") - self.session_key= re.search(r'\d{3,30}', r.content).group().encode('ascii') + self.session_key = re.search(r'\d{3,30}', r.content).group().encode('ascii') + return self.session_key def get_dhcpinfo(self): @@ -108,6 +109,7 @@ def show_active_dev(self): hostnames = [] display_list = [] count = 1 + print "\nShowing Currently Active Devices.\n" for hostname, mac in self.host_and_mac: for active_clients in self.active_dev: if active_clients in mac: @@ -144,26 +146,12 @@ def show_blocked_dev(self): print i.text + '\n' - def set_hostname(self, custom_name, mac_address): - ''' - Set custom hostname for a device. For example: - >>> DESKTOP-1RXG23 --> My-PC - ''' - self.get_dhcpinfo() - custom_hostnames = {} - self.host_and_mac = dict(zip(self.dev_hostname, self.mac_address)) - for i in self.host_and_mac.items(): - if mac_address in i: - del(self.host_and_mac[i[0]]) - self.host_and_mac[custom_name] = mac_address - - def reboot_router(self): ''' Reboots Router. ''' r, soup = self.scrape_page(self.mask + ("rebootinfo.cgi?sessionKey=%s") % self.session_key) - print "Rebooted." + print "Router has been succesfully rebooted." def time_restriction(self): From cf4c7af1cc6d6fe9f8ffda47deda86118fd65662 Mon Sep 17 00:00:00 2001 From: Rafay Ghafoor Date: Fri, 1 Sep 2017 23:24:00 +0500 Subject: [PATCH 11/11] UPDATED --- README.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f434174..f3f3c18 100755 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ A PTCL-Router API. - Obtain station information, showing their hostnames alongside for better readability (devices currently connected to the router). - Obtain DHCP information. - Block and unblock devices using their mac addresses. -- Block and unblock devices using their predefined aliases. +- Block and unblock devices using their predefined aliases. - Reboot router. - Over-ride hostnames associated to the mac address with custom hostnames. - Display blocked devices. @@ -19,13 +19,13 @@ A PTCL-Router API. ```python >>> python ptcl.py -``` +``` **Shows currently active devices and provides an option to block device from the display.** -```python +```python >>> python ptcl.py -b -``` +``` **Shows DHCP info for all devices connected in a day.** @@ -51,7 +51,7 @@ A PTCL-Router API. - [ ] Changing SSID-Name. - [ ] Adding a method to change router password. - [ ] Add CLI MODE for unblocking devices. -- [ ] Option to change frequency 2.4 Ghz or 5 Ghz. +- [ ] Option to change frequency 2.4 Ghz or 5 Ghz. - [ ] Option to change router transmission power. - [ ] Improving display for blocked devices. - [ ] Exclude android devices from station info and dhcp info (Optional). @@ -68,7 +68,3 @@ A PTCL-Router API. - [X] Testing on other routers from the same vendor. - [X] Reboot router from script. - [X] Display number of active devices. - - - -