Last active
January 26, 2023 20:38
-
-
Save thevickypedia/3c5aa9309fe91869f2b7780f63f54e97 to your computer and use it in GitHub Desktop.
Scan devices attached to router - At&t
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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