blob: ae0f599ced98e4346ab9d78194c6efb99811c104 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
2'''
3Created on 26-Oct-2012
4
5@author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
6
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
12
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20
21
22MininetCliDriver is the basic driver which will handle the Mininet functions
23'''
admin2a9548d2014-06-17 14:08:07 -070024import traceback
adminbae64d82013-08-01 10:50:15 -070025import pexpect
26import struct
27import fcntl
28import os
29import signal
30import re
31import sys
32import core.teston
33sys.path.append("../")
34from drivers.common.cli.emulatordriver import Emulator
35from drivers.common.clidriver import CLI
36from time import time
37
38class RemoteMininetDriver(Emulator):
39 '''
adminaeedddd2013-08-02 15:14:15 -070040 RemoteMininetCliDriver is the basic driver which will handle the Mininet functions
41 The main different between this and the MininetCliDriver is that this one does not build the mininet.
42 It assumes that there is already a mininet running on the target.
adminbae64d82013-08-01 10:50:15 -070043 '''
44 def __init__(self):
45 super(Emulator, self).__init__()
46 self.handle = self
47 self.wrapped = sys.modules[__name__]
48 self.flag = 0
49
50 def connect(self, **connectargs):
51 #,user_name, ip_address, pwd,options):
52 # Here the main is the TestON instance after creating all the log handles.
53 for key in connectargs:
54 vars(self)[key] = connectargs[key]
55
56 self.name = self.options['name']
57 self.handle = super(RemoteMininetDriver, self).connect(user_name = self.user_name, ip_address = self.ip_address,port = None, pwd = self.pwd)
58
59 self.ssh_handle = self.handle
60
61 # Copying the readme file to process the
62 if self.handle :
63 return main.TRUE
64
65 else :
66 main.log.error("Connection failed to the host "+self.user_name+"@"+self.ip_address)
67 main.log.error("Failed to connect to the Mininet")
68 return main.FALSE
admin98ad0092014-07-23 16:51:07 -070069
70#*********************************************************************************************
71#*********************************************************************************************
72# checkForLoss will determine if any of the pings had any packets lost during the course of
73# the pingLong.
74#*********************************************************************************************
75#*********************************************************************************************
76
admin2580a0e2014-07-29 11:24:34 -070077 def checkForLoss(self, pingList):
Jon Hall6c794f32014-08-14 13:33:13 -070078 '''
79 Returns main.FALSE for 0% packet loss and
80 Returns main.ERROR if "found multiple mininet" is found and
81 Returns main.TRUE else
82 '''
Jon Hall368769f2014-11-19 15:43:35 -080083 #TODO: maybe we want to return the % loss instead? This way we can set an acceptible loss %.
84 #EX: 393 packets transmitted, 380 received, 3% packet loss, time 78519ms
85 # we may need to return a float to get around rounding errors
86
admin98ad0092014-07-23 16:51:07 -070087 import os
admin2580a0e2014-07-29 11:24:34 -070088 self.handle.sendline("")
89 self.handle.expect("\$")
Jon Hall368769f2014-11-19 15:43:35 -080090 #Clear any output waiting in the bg from killing pings
91 self.handle.sendline("")
92 self.handle.expect("\$")
admin2580a0e2014-07-29 11:24:34 -070093 self.handle.sendline("cat " + pingList)
94 self.handle.expect(pingList)
95 self.handle.expect("\$")
96 outputs = self.handle.before + self.handle.after
97 if re.search(" 0% packet loss",outputs):
admin98ad0092014-07-23 16:51:07 -070098 return main.FALSE
admin2580a0e2014-07-29 11:24:34 -070099 elif re.search("found multiple mininet",outputs):
100 return main.ERROR
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700101 else:
Jon Hall2ef1e9e2014-11-18 14:27:05 -0500102 main.log.error("Error, unexpected output in the ping file")
103 main.log.warn( outputs )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700104 return main.TRUE
105
admin98ad0092014-07-23 16:51:07 -0700106
107
adminbae64d82013-08-01 10:50:15 -0700108 def pingLong(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700109 '''
110 Starts a continuous ping on the mininet host outputing to a file in the /tmp dir.
111 '''
Jon Hall6c794f32014-08-14 13:33:13 -0700112 self.handle.sendline("")
113 self.handle.expect("\$")
admin98ad0092014-07-23 16:51:07 -0700114 args = utilities.parse_args(["SRC","TARGET","PINGTIME"],**pingParams)
Jon Hall6c794f32014-08-14 13:33:13 -0700115 precmd = "sudo rm /tmp/ping." + args["SRC"]
admin530b4c92013-08-14 16:54:35 -0700116 self.execute(cmd=precmd,prompt="(.*)",timeout=10)
Jon Hall94fd0472014-12-08 11:52:42 -0800117 command = "sudo mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -i .2 -w " + str(args['PINGTIME']) + " -D > /tmp/ping." + args["SRC"] + " &"
adminbae64d82013-08-01 10:50:15 -0700118 main.log.info( command )
119 self.execute(cmd=command,prompt="(.*)",timeout=10)
Jon Hall6c794f32014-08-14 13:33:13 -0700120 self.handle.sendline("")
121 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700122 return main.TRUE
123
124 def pingstatus(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700125 '''
126 Tails the respective ping output file and check that there is a moving "64 bytes"
127 '''
Jon Hall6c794f32014-08-14 13:33:13 -0700128 self.handle.sendline("")
129 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700130 args = utilities.parse_args(["SRC"],**pingParams)
131 self.handle.sendline("tail /tmp/ping." + args["SRC"])
132 self.handle.expect("tail")
133 self.handle.expect("\$")
134 result = self.handle.before + self.handle.after
Jon Hall6c794f32014-08-14 13:33:13 -0700135 self.handle.sendline("")
136 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700137 if re.search('Unreachable', result ):
138 main.log.info("Unreachable found in ping logs...")
139 return main.FALSE
140 elif re.search('64\sbytes', result):
141 main.log.info("Pings look good")
142 return main.TRUE
143 else:
144 main.log.info("No, or faulty ping data...")
145 return main.FALSE
146
Jon Hall6c794f32014-08-14 13:33:13 -0700147 def pingKill(self, testONUser, testONIP):
adminaeedddd2013-08-02 15:14:15 -0700148 '''
149 Kills all continuous ping processes.
150 Then copies all the ping files to the TestStation.
151 '''
152 import time
Jon Hall6c794f32014-08-14 13:33:13 -0700153 self.handle.sendline("")
154 self.handle.expect("\$")
admin2580a0e2014-07-29 11:24:34 -0700155 command = "sudo kill -SIGINT `pgrep ping`"
adminbae64d82013-08-01 10:50:15 -0700156 main.log.info( command )
157 self.execute(cmd=command,prompt="(.*)",timeout=10)
Jon Hall6c794f32014-08-14 13:33:13 -0700158 #Commenting out in case TestON and MN are on the same machine. scp overrights the file anyways
159 #main.log.info( "Removing old ping data" )
160 #command = "rm /tmp/ping.*"
161 #os.popen(command)
162 #time.sleep(2)
adminbae64d82013-08-01 10:50:15 -0700163 main.log.info( "Transferring ping files to TestStation" )
Jon Hall6c794f32014-08-14 13:33:13 -0700164 command = "scp /tmp/ping.* "+ str(testONUser) + "@" + str(testONIP) + ":/tmp/"
adminbae64d82013-08-01 10:50:15 -0700165 self.execute(cmd=command,prompt="100%",timeout=20)
Jon Hall2ef1e9e2014-11-18 14:27:05 -0500166 #Make sure the output is cleared
167 self.handle.sendline("")
168 self.handle.expect("\$")
169 self.handle.sendline("")
170 self.handle.expect("\$")
Jon Hall6c794f32014-08-14 13:33:13 -0700171 self.handle.sendline("")
Jon Hall368769f2014-11-19 15:43:35 -0800172 i=self.handle.expect(["password","\$"])
173 if i == 0:
174 main.log.error("Error, sudo asking for password")
175 main.log.error(self.handle.before)
176 return main.FALSE
177 else:
178 return main.TRUE
admin2580a0e2014-07-29 11:24:34 -0700179
180 def pingLongKill(self):
181 import time
Jon Hall6c794f32014-08-14 13:33:13 -0700182 self.handle.sendline("")
183 self.handle.expect("\$")
admin2580a0e2014-07-29 11:24:34 -0700184 command = "sudo kill -SIGING `pgrep ping`"
185 main.log.info(command)
186 self.execute(cmd=command,prompt="(.*)",timeout=10)
Jon Hall6c794f32014-08-14 13:33:13 -0700187 self.handle.sendline("")
188 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700189 return main.TRUE
shahshreya28bb18e2014-11-17 10:26:23 -0800190
191 def pingHostOptical(self,**pingParams):
192 '''
193 This function is only for Packey Optical related ping
194 Use the next pingHost() function for all normal scenarios)
195 Ping from one mininet host to another
196 Currently the only supported Params: SRC and TARGET
197 '''
198 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
199 #command = args["SRC"] + " ping -" + args["CONTROLLER"] + " " +args ["TARGET"]
200 command = args["SRC"] + " ping "+args ["TARGET"]+" -c 1 -i 1 -W 8"
201 try:
202 main.log.warn("Sending: " + command)
203 #response = self.execute(cmd=command,prompt="mininet",timeout=10 )
204 self.handle.sendline(command)
205 i = self.handle.expect([command,pexpect.TIMEOUT])
206 if i == 1:
207 main.log.error(self.name + ": timeout when waiting for response from mininet")
208 main.log.error("response: " + str(self.handle.before))
209 i = self.handle.expect(["mininet>",pexpect.TIMEOUT])
210 if i == 1:
211 main.log.error(self.name + ": timeout when waiting for response from mininet")
212 main.log.error("response: " + str(self.handle.before))
213 response = self.handle.before
214 except pexpect.EOF:
215 main.log.error(self.name + ": EOF exception found")
216 main.log.error(self.name + ": " + self.handle.before)
217 main.cleanup()
218 main.exit()
219 main.log.info(self.name+": Ping Response: "+ response )
220 #if utilities.assert_matches(expect=',\s0\%\spacket\sloss',actual=response,onpass="No Packet loss",onfail="Host is not reachable"):
221 if re.search(',\s0\%\spacket\sloss',response):
222 main.log.info(self.name+": no packets lost, host is reachable")
223 main.last_result = main.TRUE
224 return main.TRUE
225 else :
226 main.log.error(self.name+": PACKET LOST, HOST IS NOT REACHABLE")
227 main.last_result = main.FALSE
228 return main.FALSE
229
adminbae64d82013-08-01 10:50:15 -0700230 def pingHost(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700231 '''
232 Pings between two hosts on remote mininet
233 '''
Jon Hall6c794f32014-08-14 13:33:13 -0700234 self.handle.sendline("")
235 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700236 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
shahshreya28bb18e2014-11-17 10:26:23 -0800237 #command = "mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -c 4 -W 1 -i .2"
adminbae64d82013-08-01 10:50:15 -0700238 command = "mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -c 4 -W 1 -i .2"
239 main.log.info ( command )
240 response = self.execute(cmd=command,prompt="rtt",timeout=10 )
shahshreya28bb18e2014-11-17 10:26:23 -0800241 #self.handle.sendline("")
242 #self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700243 if utilities.assert_matches(expect=',\s0\%\spacket\sloss',actual=response,onpass="No Packet loss",onfail="Host is not reachable"):
244 main.log.info("NO PACKET LOSS, HOST IS REACHABLE")
245 main.last_result = main.TRUE
246 return main.TRUE
247 else :
248 main.log.error("PACKET LOST, HOST IS NOT REACHABLE")
249 main.last_result = main.FALSE
250 return main.FALSE
251
252
253 def checknum(self,num):
254 '''
adminaeedddd2013-08-02 15:14:15 -0700255 Verifies the correct number of switches are running
adminbae64d82013-08-01 10:50:15 -0700256 '''
257 if self.handle :
258 self.handle.sendline("")
259 self.handle.expect("\$")
260 self.handle.sendline('ifconfig -a | grep "sw.. " | wc -l')
261 self.handle.expect("wc")
262 self.handle.expect("\$")
263 response = self.handle.before
264 self.handle.sendline('ps -ef | grep "bash -ms mininet:sw" | grep -v color | wc -l')
265 self.handle.expect("color")
266 self.handle.expect("\$")
267 response2 = self.handle.before
268
269 if re.search(num, response):
270 if re.search(num, response2):
271 return main.TRUE
272 else:
273 return main.FALSE
274 else:
275 return main.FALSE
276 else :
277 main.log.error("Connection failed to the host")
278
Jon Hall73cf9cc2014-11-20 22:28:38 -0800279 def start_tcpdump(self, filename, intf = "eth0", port = "port 6633", user="admin"):
admin2a9548d2014-06-17 14:08:07 -0700280 '''
281 Runs tpdump on an intferface and saves the file
282 intf can be specified, or the default eth0 is used
283 '''
284 try:
285 self.handle.sendline("")
Jon Hall73cf9cc2014-11-20 22:28:38 -0800286 self.handle.sendline("sudo tcpdump -n -i "+ intf + " " + port + " -w " + filename.strip() + " -Z " + user + " &")
admin2a9548d2014-06-17 14:08:07 -0700287 self.handle.sendline("")
288 self.handle.sendline("")
289 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT,"\$"],timeout=10)
290 main.log.warn(self.handle.before + self.handle.after)
291 if i == 0:
292 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
293 return main.FALSE
294 elif i == 1:
295 main.log.info(self.name + ": tcpdump started on " + intf)
296 return main.TRUE
297 elif i == 2:
298 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
299 return main.FALSE
300 elif i ==3:
301 main.log.info(self.name +": " + self.handle.before)
302 return main.TRUE
303 else:
304 main.log.error(self.name + ": tcpdump - unexpected response")
305 return main.FALSE
306 except pexpect.EOF:
307 main.log.error(self.name + ": EOF exception found")
308 main.log.error(self.name + ": " + self.handle.before)
309 main.cleanup()
310 main.exit()
311 except:
312 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
313 main.log.error( traceback.print_exc() )
314 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
315 main.cleanup()
316 main.exit()
317
318 def stop_tcpdump(self):
319 "pkills tcpdump"
320 try:
321 self.handle.sendline("sudo pkill tcpdump")
322 self.handle.sendline("")
323 self.handle.sendline("")
324 self.handle.expect("\$")
325 except pexpect.EOF:
326 main.log.error(self.name + ": EOF exception found")
327 main.log.error(self.name + ": " + self.handle.before)
328 main.cleanup()
329 main.exit()
330 except:
331 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
332 main.log.error( traceback.print_exc() )
333 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
334 main.cleanup()
335 main.exit()
336
shahshreya4d79aab2014-11-07 15:20:41 -0800337 def run_optical_mn_script(self):
shahshreya28bb18e2014-11-17 10:26:23 -0800338 '''
339 This function is only meant for Packet Optical.
340 It runs the python script "optical.py" to create the packet layer(mn)
341 topology
342 '''
343 try:
344 self.handle.sendline("")
345 self.handle.expect("\$")
346 self.handle.sendline("cd ~")
347 self.handle.expect("\$")
348 self.handle.sendline("sudo python optical.py")
349 self.handle.expect(">")
350 return main.TRUE
351 except pexpect.EOF:
352 main.log.error(self.name + ": EOF exception found")
353 main.log.error(self.name + ": " + self.handle.before)
354 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700355
356 def disconnect(self):
adminaeedddd2013-08-02 15:14:15 -0700357 '''
358 Called at the end of the test to disconnect the handle.
359 '''
adminbae64d82013-08-01 10:50:15 -0700360 response = ''
361 #print "Disconnecting Mininet"
362 if self.handle:
Jon Hall2ef1e9e2014-11-18 14:27:05 -0500363 self.handle.sendline("exit")
adminbae64d82013-08-01 10:50:15 -0700364 self.handle.expect("exit")
365 self.handle.expect("(.*)")
366 response = self.handle.before
367
368 else :
369 main.log.error("Connection failed to the host")
370 response = main.FALSE
Jon Hall2ef1e9e2014-11-18 14:27:05 -0500371 return response
adminbae64d82013-08-01 10:50:15 -0700372
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700373 def get_flowTable(self, protoVersion, sw):
Jon Hall2ef1e9e2014-11-18 14:27:05 -0500374 #TODO document usage
Jon Hall94fd0472014-12-08 11:52:42 -0800375 #TODO add option to look at cookies. ignoreing them for now
santhosh9da93892014-07-28 14:11:19 -0700376 self.handle.sendline("cd")
Jon Hall2ef1e9e2014-11-18 14:27:05 -0500377 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
Jon Hall94fd0472014-12-08 11:52:42 -0800378 #print "get_flowTable(" + str(protoVersion) +" " + str(sw) +")"
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700379 #NOTE: Use format to force consistent flow table output across versions
380 if protoVersion==1.0:
Jon Hall94fd0472014-12-08 11:52:42 -0800381 command = "sudo ovs-ofctl dump-flows " + sw + " -F OpenFlow10-table_id | awk '{OFS=\",\" ; print $1 $3 $6 $7 $8}' | cut -d ',' -f 2- | sort -n -k1 -r"
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700382 self.handle.sendline(command)
Jon Hall94fd0472014-12-08 11:52:42 -0800383 self.handle.expect(["k1 -r",pexpect.EOF,pexpect.TIMEOUT])
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700384 self.handle.expect(["OFPST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
385 response = self.handle.before
386 #print "response=", response
387 return response
388 elif protoVersion==1.3:
Jon Hall94fd0472014-12-08 11:52:42 -0800389 command = "sudo ovs-ofctl dump-flows " + sw + " -O OpenFlow13 | awk '{OFS=\",\" ; print $1 $3 $6 $7}' | cut -d ',' -f 2- | sort -n -k1 -r"
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700390 self.handle.sendline(command)
Jon Hall94fd0472014-12-08 11:52:42 -0800391 self.handle.expect(["k1 -r",pexpect.EOF,pexpect.TIMEOUT])
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700392 self.handle.expect(["OFPST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700393 response = self.handle.before
394 #print "response=", response
Jon Hall94fd0472014-12-08 11:52:42 -0800395 return response
396 else:
397 main.log.error("Unknown protoVersion in get_flowTable(). given: ("+str(type(protoVersion))+") '"+str(protoVersion)+"'")
398
santhosh19fd8032014-07-29 11:56:17 -0700399
400 def flow_comp(self,flow1,flow2):
401 if flow1==flow2:
402 return main.TRUE
403 else:
Jon Hall6c794f32014-08-14 13:33:13 -0700404 main.log.info("Flow tables do not match, printing tables:")
Jon Hall94fd0472014-12-08 11:52:42 -0800405 main.log.info("Flow Table 1:")
406 main.log.info(flow1)
407 main.log.info("Flow Table 2:")
408 main.log.info(flow2)
santhosh19fd8032014-07-29 11:56:17 -0700409 return main.FALSE
410
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700411 def setIpTablesOUTPUT(self, dst_ip, dst_port, action='add', packet_type='tcp',rule='DROP'):
412 '''
413 Description:
414 add or remove iptables rule to DROP (default) packets from specific IP and PORT
415 Usage:
416 * specify action ('add' or 'remove')
417 when removing, pass in the same argument as you would add. It will
418 delete that specific rule.
419 * specify the destination ip to block with dst_ip
420 * specify destination port to block to dst_port
421 * optional packet type to block (default tcp)
422 * optional iptables rule (default DROP)
423 WARNING:
424 * This function uses root privilege iptables command which may result in
425 unwanted network errors. USE WITH CAUTION
426 '''
427 import re
428 import time
429
430 #NOTE*********
431 # The strict checking methods of this driver function is intentional
432 # to discourage any misuse or error of iptables, which can cause
433 # severe network errors
434 #*************
435
436 #NOTE: Sleep needed to give some time for rule to be added and registered
437 # to the instance
438 time.sleep(5)
439
440 action_type = action.lower()
441 if action_type != 'add' and action_type !='remove':
442 main.log.error("Invalid action type. 'add' or 'remove' table rule")
443 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
444 #NOTE: Currently only supports rules DROP, ACCEPT, and LOG
445 main.log.error("Invalid rule. 'DROP' or 'ACCEPT' or 'LOG' only.")
446 return
447 return
448 else:
449
450 #If there is no existing rule in the iptables, we will see an
451 #'iptables:'... message. We expect to see this message.
452 #Otherwise, if there IS an existing rule, we will get the prompt
453 # back, hence why we expect $ for remove type. We want to remove
454 # an already existing rule
455
456 if action_type == 'add':
457 #NOTE: "iptables:" expect is a result of return from the command
458 # iptables -C ...
459 # Any changes by the iptables command return string
460 # will result in failure of the function. (deemed unlikely
461 # at the time of writing this function)
462 #Check for existing rules on current input
463 self.handle.sendline("")
464 self.handle.expect("\$")
465 self.handle.sendline("sudo iptables -C OUTPUT -p "+str(packet_type)+
466 " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
467 i = self.handle.expect(["iptables:", "\$"])
468 print i
469 print self.handle.before
470 print "after: "
471 print self.handle.after
472
473 elif action_type == 'remove':
474 #Check for existing rules on current input
475 self.handle.sendline("")
476 self.handle.expect("\$")
477 self.handle.sendline("sudo iptables -C OUTPUT -p "+str(packet_type)+
478 " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
479 self.handle.expect("\$")
480 print "before: "
481 print self.handle.before
482 actual_string = self.handle.after
483 expect_string = "iptables:"
484 print "Actual String:"
485 print actual_string
486
487 if re.search(expect_string, actual_string):
488 match_result = main.TRUE
489 else:
490 match_result = main.FALSE
491 #If match_result is main.TRUE, it means there is no matching rule.
492
493 #If tables does not exist and expected prompt is returned, go ahead and
494 #add iptables rule
495 if match_result == main.TRUE:
496 #Ensure action type is add
497 if action_type == 'add':
498 #-A is the 'append' action of iptables
499 action_add = '-A'
500 try:
501 self.handle.sendline("")
502 self.handle.sendline("sudo iptables "+action_add+" OUTPUT -p "+str(packet_type)+
503 " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
504
505 info_string = "Rules added to "+str(self.name)
506 info_string += "iptable rule added to block IP: "+str(dst_ip)
507 info_string += "Port: "+str(dst_port)+" Rule: "+str(rule)
508
509 main.log.info(info_string)
510
511 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
512 except pexpect.TIMEOUT:
513 main.log.error(self.name + ": Timeout exception in setIpTables function")
514 except:
515 main.log.error( traceback.print_exc())
516 main.cleanup()
517 main.exit()
518 else:
519 main.log.error("Given rule already exists, but attempted to add it")
520 #If match_result is 0, it means there IS a matching rule provided
521 elif match_result == main.FALSE:
522 #Ensure action type is remove
523 if action_type == 'remove':
524 #-D is the 'delete' rule of iptables
525 action_remove = '-D'
526 try:
527 self.handle.sendline("")
528 #Delete a specific rule specified into the function
529 self.handle.sendline("sudo iptables "+action_remove+" OUTPUT -p "+str(packet_type)+
530 " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
531
532 info_string = "Rules removed from "+str(self.name)
533 info_string += " iptables rule removed from blocking IP: "+str(dst_ip)
534 info_string += " Port: "+str(dst_port)+" Rule: "+str(rule)
535
536 main.log.info(info_string)
537
538 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
539 except pexpect.TIMEOUT:
540 main.log.error(self.name + ": Timeout exception in setIpTables function")
541 except:
542 main.log.error( traceback.print_exc())
543 main.cleanup()
544 main.exit()
545 else:
546 main.log.error("Given rule does not exist, but attempted to remove it")
547 else:
548 #NOTE: If a bad usage of this function occurs, exit the entire test
549 main.log.error("Bad rule given for iptables. Exiting...")
550 main.cleanup()
551 main.exit()
552
553
adminbae64d82013-08-01 10:50:15 -0700554if __name__ != "__main__":
555 import sys
556 sys.modules[__name__] = RemoteMininetDriver()