reset a3, kut Charlie ;)
[tt2015.git] / a3 / code / jtorx / client / sender.py
1 from scapy.all import *
2
3 verbose = 0
4
5 def vb_print(msg):
6 global verbose
7 if verbose == 1:
8 print msg
9
10 # the sender sends packets with configurable parameters to a server and retrieves responses
11 class Sender:
12 # information on the SUT
13 def __init__(self, serverIP, serverPort=8000,
14 networkInterface="lo", isLocal=True, senderPortMinimum=20000,
15 senderPortMaximum=40000, portNumberFile="sn.txt",
16 isVerbose=0, waitTime=1):
17
18
19 # file where the last sender port used is stored
20 self.portNumberFile = portNumberFile;
21
22 # when choosing a fresh port, a new port is chosen
23 # within boundaries defined by the parameters below
24 self.senderPortMinimum = senderPortMinimum
25 self.senderPortMaximum = senderPortMaximum
26
27 # data on sender and server needed to send packets
28 self.serverIP = serverIP
29 self.serverPort = serverPort
30 self.networkInterface = networkInterface
31 self.senderPort = self.getNextPort()
32 self.isLocal = isLocal
33
34 # time to wait for a response from the server before concluding a timeout
35 self.waitTime = waitTime
36
37 # verbose or not
38 self.isVerbose = isVerbose
39
40 # variables added so you can easily test the last system response
41 self.lastSeqReceived = None
42 self.lastAckReceived = None
43 self.isTimeout = None
44 self.lastFlagsReceived = None
45 self.lastDataReceived = None
46
47
48 # chooses a new port to send packets from
49 def refreshNetworkPort(self):
50 vb_print("previous local port: " + str(self.senderPort))
51 self.senderPort = self.getNextPort()
52 vb_print("next local port: " + str(self.senderPort) + "\n")
53 return self.senderPort
54
55 # gets a new port number, an increment of the old within the specified limits. Uses a file.
56 def getNextPort(self):
57 f = open(self.portNumberFile, "a+")
58 f.seek(0)
59 line = f.readline()
60 if line == '' or int(line) < self.senderPortMinimum:
61 networkPort = self.senderPortMinimum
62 else:
63 networkPort = (int(line) + 1) % self.senderPortMaximum
64 f.closed
65 f = open(self.portNumberFile, "w")
66 f.write(str(networkPort))
67 f.closed
68 return networkPort
69
70 # send a packet onto the network with the given parameters, and return the response packet
71 # in case of a timeout, returns None, otherwise, returns the tuple (flags, seqNo, ackNo)
72 def sendPacket(self, flagsSet, seqNr, ackNr, data = None):
73 packet = self.createPacket(flagsSet, seqNr, ackNr, data)
74 # consider adding the parameter: iface="ethx" if you don't receive a response. Also consider increasing the wait time
75 scapyResponse = sr1(packet, timeout=self.waitTime, verbose=self.isVerbose)
76 if scapyResponse is not None:
77 # scapyResponse.show()
78 # ^^ in case you want to show the packet content
79 # here is what you store from every packet response
80 if Raw not in scapyResponse:
81 response = (self.intToFlags(scapyResponse[TCP].flags), scapyResponse[TCP].seq, scapyResponse[TCP].ack, None)
82 else:
83 response = (self.intToFlags(scapyResponse[TCP].flags), scapyResponse[TCP].seq, scapyResponse[TCP].ack, scapyResponse[Raw].load)
84 else:
85 response = "Timeout"
86 return response
87
88 # function that creates packet from data strings/integers
89 # data is used for attaching data to the packet
90 def createPacket(self, tcpFlagsSet, seqNr, ackNr, data=None):
91 vb_print("" + tcpFlagsSet + " " + str(seqNr) + " " + str(ackNr))
92 pIP = IP(dst=self.serverIP, flags="DF")
93 pTCP = TCP(sport=self.senderPort,
94 dport=self.serverPort,
95 seq=seqNr,
96 ack=ackNr,
97 flags=tcpFlagsSet)
98 if data is None:
99 p = pIP / pTCP
100 else:
101 p = pIP / pTCP / Raw(load=data)
102 return p
103
104 # check whether there is a 1 at the given bit-position of the integer
105 def checkForFlag(self, x, flagPosition):
106 if x & 2 ** flagPosition == 0:
107 return False
108 else:
109 return True
110
111 # the flags-parameter of a network packets is returned as an int, this function converts
112 # it to a string (such as "FA" if the Fin-flag and Ack-flag have been set)
113 def intToFlags(self, x):
114 result = ""
115 if self.checkForFlag(x, 0):
116 result = result + "F"
117 if self.checkForFlag(x, 1):
118 result = result + "S"
119 if self.checkForFlag(x, 2):
120 result = result + "R"
121 if self.checkForFlag(x, 3):
122 result = result + "P"
123 if self.checkForFlag(x, 4):
124 result = result + "A"
125 return result
126
127 # sends input over the network to the server
128 def sendInput(self, input1, seqNr, ackNr, data = None):
129 conf.sniff_promisc = False
130 conf.iface = self.networkInterface
131 if self.isLocal == True:
132 conf.L3socket = L3RawSocket # if the connection is local/localhost, use l3 raw sockets
133 vb_print("sending: "+ str((input1, seqNr, ackNr, data)))
134 response = self.sendPacket(input1, seqNr, ackNr, data)
135
136 # updating sender state variables
137 if response != "Timeout":
138 (self.lastFlagsReceived, self.lastSeqReceived, self.lastAckReceived, self.lastDataReceived) = response
139 self.isTimeout = False
140 else:
141 self.isTimeout = True
142
143 # printing response
144 vb_print("received: "+ str(response))
145 return response
146
147 # resets the connection by changing the port number. On some OSes (Win 8) upon hitting a certain number of
148 # connections opened on a port, packets are sent to close down connections.
149 def sendReset(self):
150 self.refreshNetworkPort()