from prometheus_client import start_http_server, Gauge import time import ping3 from scapy.all import ARP, Ether, srp, IP, ICMP pcs = [ {"ip": "10.10.20.28", "pc":13, "location": "HUB1"}, {"ip": "10.10.20.82", "pc":12, "location": "HUB1"}, {"ip": "10.10.20.76", "pc":11, "location": "HUB1"}, {"ip": "10.10.20.31", "pc":16, "location": "HUB1"}, {"ip": "10.10.20.27", "pc":15, "location": "HUB1"}, {"ip": "10.10.20.26", "pc":14, "location": "HUB1"}, {"ip": "10.10.20.40", "pc":23, "location": "HUB2"}, {"ip": "10.10.20.30", "pc":22, "location": "HUB2"}, {"ip": "10.10.20.43", "pc":21, "location": "HUB2"}, {"ip": "10.10.20.66", "pc":26, "location": "HUB2"}, {"ip": "10.10.20.52", "pc":25, "location": "HUB2"}, {"ip": "10.10.20.34", "pc":24, "location": "HUB2"}, {"ip": "10.10.20.104", "pc":33, "location": "HUB3"}, {"ip": "10.10.20.60", "pc":32, "location": "HUB3"}, {"ip": "10.10.20.4", "pc":31, "location": "HUB3"}, {"ip": "10.10.20.103", "pc":36, "location": "HUB3"}, {"ip": "10.10.20.65", "pc":35, "location": "HUB3"}, {"ip": "10.10.20.5", "pc":34, "location": "HUB3"}, {"ip": "10.10.20.33", "pc":43, "location": "HUB4"}, {"ip": "10.10.20.16", "pc":42, "location": "HUB4"}, {"ip": "10.10.20.22", "pc":41, "location": "HUB4"}, {"ip": "10.10.20.8", "pc":46, "location": "HUB4"}, {"ip": "10.10.20.70", "pc":45, "location": "HUB4"}, {"ip": "10.10.20.29", "pc":44, "location": "HUB4"}, {"ip": "10.10.20.18", "pc":53, "location": "HUB5"}, {"ip": "10.10.20.9", "pc":52, "location": "HUB5"}, {"ip": "10.10.20.46", "pc":51, "location": "HUB5"}, {"ip": "10.10.20.10", "pc":56, "location": "HUB5"}, {"ip": "10.10.20.86", "pc":55, "location": "HUB5"}, {"ip": "10.10.20.127", "pc":54, "location": "HUB5"}, {"ip": "10.10.20.98", "pc":63, "location": "HUB6"}, {"ip": "10.10.20.137", "pc":62, "location": "HUB6"}, {"ip": "10.10.20.15", "pc":61, "location": "HUB6"}, {"ip": "10.10.20.72", "pc":66, "location": "HUB6"}, {"ip": "10.10.20.21", "pc":65, "location": "HUB6"}, {"ip": "10.10.20.90", "pc":64, "location": "HUB6"}, {"ip": "10.10.20.88", "pc":73, "location": "HUB7"}, {"ip": "10.10.20.58", "pc":72, "location": "HUB7"}, {"ip": "10.10.20.132", "pc":71, "location": "HUB7"}, {"ip": "10.10.20.25", "pc":76, "location": "HUB7"}, {"ip": "10.10.20.74", "pc":75, "location": "HUB7"}, {"ip": "10.10.20.87", "pc":74, "location": "HUB7"}, ] pc_status = Gauge('pc_status', 'Status of PCs (1 = online, 0 = offline)', ['ip', 'location', 'pc'] ) def arp_scan(network): """ Perform an ARP scan on the given network (e.g., '10.10.20.0/24'). Returns a dictionary mapping IP addresses to MAC addresses. """ # Create an ARP request packet for the network arp = ARP(pdst=network) # Create an Ethernet frame with a broadcast destination MAC ether = Ether(dst="ff:ff:ff:ff:ff:ff") packet = ether / arp # Send the packet and collect responses result = srp(packet, timeout=3, verbose=0)[0] devices = {} for sent, received in result: devices[received.psrc] = received.hwsrc return devices def ping_pc(ip): """ Ping a PC and return True if online, False if offline. """ try: response = ping3.ping(ip, timeout=1) return response is not None except Exception: return False def update_metrics(): """ Update Prometheus metrics with the status of each PC. """ for pc in pcs: ip = pc["ip"] location = pc["location"] status = ping_pc(ip) pc_status.labels(ip=ip, location=location, pc=pc["ip"]).set(1 if status else 0) def update_metrics_arp(): """ Update Prometheus metrics with the status of each PC using ARP scanning. Only works within your local subnet. """ # Define your network range (adjust if necessary) network = "10.10.20.0/24" # Perform an ARP scan on the network devices = arp_scan(network) for pc in pcs: ip = pc["ip"] location = pc["location"] # Mark as online if the IP was found in the ARP scan status = 1 if ip in devices else 0 pc_status.labels(ip=ip, location=location, pc=str(pc["pc"])).set(status) if __name__ == '__main__': # Start the Prometheus HTTP server on port 8000 start_http_server(8003) print("Prometheus metrics server started on port 8000") update_fn = update_metrics_arp # Continuously update metrics while True: update_fn() time.sleep(15) # Update every 15 seconds