blob: 4510374dd1f7503a3e3443e8cbc8e8bb3ec024ee [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001#!/usr/bin/python
2
3import urllib2
4import json
5import re
6import sys
7
8from optparse import OptionParser
9
10sys.path.append('~/floodlight/target/gen-py')
11sys.path.append('~/floodlight/thrift/lib/py')
12
13from packetstreamer import PacketStreamer
14from packetstreamer.ttypes import *
15
16from thrift import Thrift
17from thrift.transport import TSocket
18from thrift.transport import TTransport
19from thrift.protocol import TBinaryProtocol
20
21SESSIONID = 'sessionId'
22usage = "usage: %prog [options]"
23parser = OptionParser(usage=usage, version="%prog 1.0")
24parser.add_option("-c", "--controller", dest="controller", metavar="CONTROLLER_IP",
25 default="127.0.0.1", help="controller's IP address")
26parser.add_option("-m", "--mac", dest="mac", metavar="HOST_MAC",
27 help="The host mac address to trace the OF packets")
28
29(options, args) = parser.parse_args()
30
31def validateIp(ip):
32 ipReg = ("(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
33 "\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
34 "\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
35 "\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")
36 m = re.compile(ipReg).match(ip)
37 if m:
38 return True
39 else :
40 return False
41
42def validateMac(mac):
43 macReg = '([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}' # same regex as above
44 m = re.compile(macReg).match(mac)
45 if m:
46 return True
47 else :
48 return False
49
50if not validateIp(options.controller):
51 parser.error("Invalid format for ip address.")
52
53if not options.mac:
54 parser.error("-m or --mac option is required.")
55
56if not validateMac(options.mac):
57 parser.error("Invalid format for mac address. Format: xx:xx:xx:xx:xx:xx")
58
59controller = options.controller
60host = options.mac
61
62url = 'http://%s:8080/wm/core/packettrace/json' % controller
63filter = {'mac':host, 'direction':'both', 'period':1000}
64post_data = json.dumps(filter)
65request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
66response_text = None
67
68def terminateTrace(sid):
69 global controller
70
71 filter = {SESSIONID:sid, 'period':-1}
72 post_data = json.dumps(filter)
73 url = 'http://%s:8080/wm/core/packettrace/json' % controller
74 request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
75 try:
76 response = urllib2.urlopen(request)
77 response_text = response.read()
78 except Exception, e:
79 # Floodlight may not be running, but we don't want that to be a fatal
80 # error, so we just ignore the exception in that case.
81 print "Exception:", e
82
83try:
84 response = urllib2.urlopen(request)
85 response_text = response.read()
86except Exception, e:
87 # Floodlight may not be running, but we don't want that to be a fatal
88 # error, so we just ignore the exception in that case.
89 print "Exception:", e
90 exit
91
92if not response_text:
93 print "Failed to start a packet trace session"
94 sys.exit()
95
96response_text = json.loads(response_text)
97
98sessionId = None
99if SESSIONID in response_text:
100 sessionId = response_text[SESSIONID]
101else:
102 print "Failed to start a packet trace session"
103 sys.exit()
104
105try:
106
107 # Make socket
108 transport = TSocket.TSocket('localhost', 9090)
109
110 # Buffering is critical. Raw sockets are very slow
111 transport = TTransport.TFramedTransport(transport)
112
113 # Wrap in a protocol
114 protocol = TBinaryProtocol.TBinaryProtocol(transport)
115
116 # Create a client to use the protocol encoder
117 client = PacketStreamer.Client(protocol)
118
119 # Connect!
120 transport.open()
121
122 while 1:
123 packets = client.getPackets(sessionId)
124 for packet in packets:
125 print "Packet: %s"% packet
126 if "FilterTimeout" in packet:
127 sys.exit()
128
129except Thrift.TException, e:
130 print '%s' % (e.message)
131 terminateTrace(sessionId)
132
133except KeyboardInterrupt, e:
134 terminateTrace(sessionId)
135
136# Close!
137transport.close()
138