diff --git a/example/packetStreamerClientExample.py b/example/packetStreamerClientExample.py new file mode 100755 index 0000000000000000000000000000000000000000..4510374dd1f7503a3e3443e8cbc8e8bb3ec024ee --- /dev/null +++ b/example/packetStreamerClientExample.py @@ -0,0 +1,138 @@ +#!/usr/bin/python + +import urllib2 +import json +import re +import sys + +from optparse import OptionParser + +sys.path.append('~/floodlight/target/gen-py') +sys.path.append('~/floodlight/thrift/lib/py') + +from packetstreamer import PacketStreamer +from packetstreamer.ttypes import * + +from thrift import Thrift +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol + +SESSIONID = 'sessionId' +usage = "usage: %prog [options]" +parser = OptionParser(usage=usage, version="%prog 1.0") +parser.add_option("-c", "--controller", dest="controller", metavar="CONTROLLER_IP", + default="127.0.0.1", help="controller's IP address") +parser.add_option("-m", "--mac", dest="mac", metavar="HOST_MAC", + help="The host mac address to trace the OF packets") + +(options, args) = parser.parse_args() + +def validateIp(ip): + ipReg = ("(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + "\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + "\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + "\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)") + m = re.compile(ipReg).match(ip) + if m: + return True + else : + return False + +def validateMac(mac): + macReg = '([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}' # same regex as above + m = re.compile(macReg).match(mac) + if m: + return True + else : + return False + +if not validateIp(options.controller): + parser.error("Invalid format for ip address.") + +if not options.mac: + parser.error("-m or --mac option is required.") + +if not validateMac(options.mac): + parser.error("Invalid format for mac address. Format: xx:xx:xx:xx:xx:xx") + +controller = options.controller +host = options.mac + +url = 'http://%s:8080/wm/core/packettrace/json' % controller +filter = {'mac':host, 'direction':'both', 'period':1000} +post_data = json.dumps(filter) +request = urllib2.Request(url, post_data, {'Content-Type':'application/json'}) +response_text = None + +def terminateTrace(sid): + global controller + + filter = {SESSIONID:sid, 'period':-1} + post_data = json.dumps(filter) + url = 'http://%s:8080/wm/core/packettrace/json' % controller + request = urllib2.Request(url, post_data, {'Content-Type':'application/json'}) + try: + response = urllib2.urlopen(request) + response_text = response.read() + except Exception, e: + # Floodlight may not be running, but we don't want that to be a fatal + # error, so we just ignore the exception in that case. + print "Exception:", e + +try: + response = urllib2.urlopen(request) + response_text = response.read() +except Exception, e: + # Floodlight may not be running, but we don't want that to be a fatal + # error, so we just ignore the exception in that case. + print "Exception:", e + exit + +if not response_text: + print "Failed to start a packet trace session" + sys.exit() + +response_text = json.loads(response_text) + +sessionId = None +if SESSIONID in response_text: + sessionId = response_text[SESSIONID] +else: + print "Failed to start a packet trace session" + sys.exit() + +try: + + # Make socket + transport = TSocket.TSocket('localhost', 9090) + + # Buffering is critical. Raw sockets are very slow + transport = TTransport.TFramedTransport(transport) + + # Wrap in a protocol + protocol = TBinaryProtocol.TBinaryProtocol(transport) + + # Create a client to use the protocol encoder + client = PacketStreamer.Client(protocol) + + # Connect! + transport.open() + + while 1: + packets = client.getPackets(sessionId) + for packet in packets: + print "Packet: %s"% packet + if "FilterTimeout" in packet: + sys.exit() + +except Thrift.TException, e: + print '%s' % (e.message) + terminateTrace(sessionId) + +except KeyboardInterrupt, e: + terminateTrace(sessionId) + +# Close! +transport.close() +