-
Notifications
You must be signed in to change notification settings - Fork 1
/
routeloop.py
105 lines (75 loc) · 2.36 KB
/
routeloop.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/python3
# Automatically detects any routing loop in the given networks
# Author: dune-official
from ipaddress import IPv4Network
from sys import argv
from scapy.sendrecv import AsyncSniffer, send
from scapy.layers.inet import IP, ICMP
from scapy.config import conf
from time import sleep, perf_counter_ns
from random import shuffle, seed
# disables verbose output from scapy (still displays warnings)
conf.verb = False
def scan_no_delay(hosts: list, verbose_: bool):
"""
Scans without a delay option.
:param hosts:
:param verbose_:
:return:
"""
asyncsn = AsyncSniffer(store=0, filter="icmp", prn=ttl_exceeded)
asyncsn.start()
for rnd_host in hosts:
ping(rnd_host)
if verbose_:
print(f"Pinged {rnd_host}")
sleep(0.1)
asyncsn.stop()
def scan_delay(hosts: list, verbose_: bool, dl: int):
"""
Scans without a delay option.
:param hosts:
:param verbose_:
:return:
"""
asyncsn = AsyncSniffer(store=0, filter="icmp", prn=ttl_exceeded)
asyncsn.start()
for rnd_host in hosts:
ping(rnd_host)
if verbose_:
print(f"Pinged {rnd_host}")
sleep(dl / 1000)
sleep(0.1)
asyncsn.stop()
def ping(addr):
# maximum TTL to really be sure
send(IP(dst=str(addr), ttl=255) / ICMP(type=8, code=0))
def ttl_exceeded(packet):
# use sprintf to search packet fields
ip = packet.sprintf("%ICMP.dst%")
if packet.sprintf("%ICMP.type%") == "time-exceeded":
print(f"\033[31;1;4m{ip}: TTL exceeded in transit, Loop suspected!\033[0m")
return
else:
return
if __name__ == '__main__':
if len(argv) > 2:
# use: routeloop.py <NETWORK> <DELAY=0> <--v optionally>
network = IPv4Network(argv[1])
delay = int(argv[2])
all_hosts = [hst for hst in network.hosts()]
seed(perf_counter_ns())
shuffle(all_hosts)
if len(argv) == 4 and argv[3] == "--v":
verbose = True
if delay:
print(f"Duration is estimated for {(network.num_addresses * delay) / 1000} s")
else:
verbose = False
if delay == 0:
scan_no_delay(all_hosts, verbose)
else:
scan_delay(all_hosts, verbose, delay)
else:
print(f"Usage: {argv[0]} [Network] [Delay] [Optional: --v]")
exit(0)