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