Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@thevickypedia
Last active January 26, 2023 20:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thevickypedia/3c5aa9309fe91869f2b7780f63f54e97 to your computer and use it in GitHub Desktop.
Save thevickypedia/3c5aa9309fe91869f2b7780f63f54e97 to your computer and use it in GitHub Desktop.
Scan devices attached to router - At&t
# pip install requests pandas lxml
import logging
import socket
from typing import Iterable, Optional, Union, Any
import pandas
import requests
from pandas import DataFrame
SOURCE = "http://{NETWORK_ID}.254/cgi-bin/devices.ha"
def get_ipaddress() -> str:
"""Get network id from the current IP address."""
socket_ = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
socket_.connect(("8.8.8.8", 80))
ip_address = socket_.getsockname()[0]
network_id = '.'.join(ip_address.split('.')[0:3])
socket_.close()
except OSError as error:
logging.warning(error)
network_id = "192.168.1"
return network_id
SOURCE = SOURCE.format(NETWORK_ID=get_ipaddress())
class Device:
"""Convert dictionary into a device object.
>>> Device
"""
def __init__(self, dictionary: dict):
"""Set dictionary keys as attributes of Device object.
Args:
dictionary: Takes the input dictionary as an argument.
"""
self.mac_address: Optional[str] = None
self.name: Optional[str] = None
self.last_activity: Optional[str] = None
self.status: Optional[str] = None
self.allocation: Optional[str] = None
self.connection_type: Optional[str] = None
self.connection_speed: Optional[Union[float, Any]] = None
self.mesh_client: Optional[str] = None
for key in dictionary:
setattr(self, key, dictionary[key])
def generate_dataframe() -> DataFrame:
"""Generate a dataframe using the devices information from router web page.
Returns:
DataFrame:
Devices list as a data frame.
"""
# pandas.set_option('display.max_rows', None)
try:
response = requests.get(url=SOURCE)
except requests.RequestException as error:
logging.error(error)
else:
if response.ok:
html_source = response.text
html_tables = pandas.read_html(html_source)
return html_tables[0]
def format_key(key: str) -> str:
"""Format the key to match the Device object."""
return key.lower().replace(' ', '_').replace('-', '_')
def get_attached_devices() -> Iterable[Device]:
"""Get all devices connected to the router.
Yields:
Iterable:
Yields each device information as a Device object.
"""
device_info = {}
dataframe = generate_dataframe()
if dataframe is None:
return
for value in dataframe.values:
if str(value[0]) == "nan":
yield Device(device_info)
device_info = {}
elif value[0] == "IPv4 Address / Name":
key = value[0].split('/')
val = value[1].split('/')
device_info[format_key(key[0].strip())] = val[0].strip()
device_info[format_key(key[1].strip())] = val[1].strip()
else:
device_info[format_key(value[0])] = value[1]
if __name__ == '__main__':
for device in get_attached_devices():
print(f"{device.name}: {device.status}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment