-
Notifications
You must be signed in to change notification settings - Fork 0
/
sender.py
120 lines (87 loc) · 3.44 KB
/
sender.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
#!/usr/bin/python
import os
from random import randint
from scapy.all import *
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
from config import *
from utils import *
class TcpSession:
def __init__(self, src, dst, sport, dport):
self.src = src
self.dst = dst
self.sport = sport
self.dport = dport
self.ip = IP(src=src, dst=dst)
self.seq = randint(10, 100) * 1000 # zero-ended for simplicity in debug time
def connect(self):
SYN = TCP(sport=self.sport, dport=self.dport, flags="S", seq=self.seq)
send(self.ip/SYN)
self.seq += 1
def ack(self, ack_seq):
pkt_to_send = self.ip / TCP(sport=self.sport, dport=self.dport, flags="A",
seq=self.seq, ack=ack_seq)
send(pkt_to_send)
def close(self, ack_seq):
pkt_to_send = self.ip / TCP(sport=self.sport, dport=self.dport, flags="FA",
seq=self.seq, ack=ack_seq)
send(pkt_to_send)
def push(self, ack_seq, data):
payload = Raw(data)
pkt_to_send = self.ip / TCP(sport=self.sport, dport=self.dport, flags="PA",
seq=self.seq, ack=ack_seq) / payload
self.seq += 1 + len(payload)
send(pkt_to_send)
class SendProxyServer(LineReceiver):
def __init__(self):
self.connections = {}
def connectionMade(self):
print "%s:%d connected." % self.transport.client
self.sendLine("HELLO %s" % self.transport.client[0]) #XXX
def lineReceived(self, line):
parts = line.split('\t')
if parts[0] == "CONNECT":
self.handle_CONNECT(*parts[1:])
elif parts[0] == "ACK":
self.handle_ACK(*parts[1:])
elif parts[0] == "CLOSE":
self.handle_CLOSE(*parts[1:])
elif parts[0] == "PUSH":
self.handle_PUSH(*parts[1:])
def handle_CONNECT(self, src, dst, sport, dport):
sport = int(sport)
dport = int(dport)
self.connections[sport] = TcpSession(src, dst, sport, dport)
self.connections[sport].connect()
def handle_ACK(self, sport, ack_seq):
sport = int(sport)
ack_seq = int(ack_seq)
if sport in self.connections:
session = self.connections[sport]
session.ack(ack_seq)
else:
print "Ooops! ACK for invalid connection: sport=%d, ack_seq=%d" % (sport, ack_seq)
def handle_CLOSE(self, sport, ack_seq):
sport = int(sport)
ack_seq = int(ack_seq)
if sport in self.connections:
session = self.connections[sport]
session.close(ack_seq)
del self.connections[sport]
self.sendLine("%d CLOSE" % sport)
else:
print "Ooops! CLOSE for invalid connection: sport=%d, ack_seq=%d" % (sport, ack_seq)
def handle_PUSH(self, sport, ack_seq, *data):
sport = int(sport)
ack_seq = int(ack_seq)
if sport in self.connections:
session = self.connections[sport]
session.push(ack_seq, '\n'.join(data))
else:
print "Ooops! PUSH for invalid connection: sport=%d, ack_seq=%d" % (sport, ack_seq)
class SendProxyServerFactory(Factory):
def buildProtocol(self, addr):
return SendProxyServer()
reactor.listenTCP(SEND_PROXY_PORT, SendProxyServerFactory())
reactor.run()