Adding ONOS Segment Routing CLI files to new repo
diff --git a/cli/trace.py b/cli/trace.py
new file mode 100755
index 0000000..a456f83
--- /dev/null
+++ b/cli/trace.py
@@ -0,0 +1,220 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#
+# Copyright (c) 2011,2012 Big Switch Networks, Inc.
+# All rights reserved.
+#
+
+from sys import stderr
+from re import compile, match, search
+from optparse import OptionParser
+from collections import defaultdict
+from subprocess import Popen, PIPE, STDOUT
+
+import socket, fcntl, struct
+def get_ipaddr(ifname):
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    ipaddr = fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))  # SIOCGIFADDR
+    return socket.inet_ntoa(ipaddr[20:24])
+
+import urllib, json
+def get_aliases(controller='localhost', controller_port=6633, ifname='eth0'):
+    url = "http://%s/rest/v1/model/switch/" % controller
+    aliases = {get_ipaddr(ifname)+':%d'%controller_port: 'controller'}
+    for switch in json.loads(urllib.urlopen(url).read()):
+        socketaddr = switch.get('socket-address')
+        if socketaddr:
+            socketaddr = socketaddr[1:]
+        alias = switch.get('alias')
+        if not alias:
+            alias = switch.get('dpid')
+        aliases[socketaddr] = alias
+    return aliases
+
+DEBUG=False
+
+class OpenFlowTracer(object):
+    # Formats
+    SUMMARY = "summary"
+    DETAIL = "detail"
+    ONELINE = "oneline"
+
+    def __init__(self, msg_filters=None, tcpdump_filter='', fmt=SUMMARY, alias=False, printer=None):
+        self.msg_filters = msg_filters
+        self.tcpdump_filter = tcpdump_filter
+        self.detail = (fmt != self.SUMMARY)
+        self.oneline = (fmt == self.ONELINE)
+        self.printer = self.prn
+        if printer:
+            self.printer = printer
+
+        self.pkt = defaultdict(str)
+        self.reading_detail = False
+        self.alias = alias
+        self.aliases = None
+        if self.alias:
+            self.aliases = get_aliases()
+
+    def run(self):
+        self.tcpdump_trace(self.tcpdump_open())
+        return
+
+    # filter packets
+    def filter(self):
+        msg_type =  self.pkt['of-msg']
+        if not msg_type:
+            return False
+        if self.msg_filters:
+            return any(map(lambda pattern: search(pattern, msg_type), self.msg_filters))
+        return True
+
+    # format packet output
+    def fmt(self):
+        pkt = self.pkt
+        sep = '\n    '
+        if self.oneline: sep = ', '
+
+        src = '%s:%s' % (pkt['src-ip'], pkt['src-port'])
+        dst = '%s:%s' % (pkt['dst-ip'], pkt['dst-port'])
+        if self.alias:
+            if not self.aliases.get(src) or not self.aliases.get(dst):
+                self.aliases = get_aliases()
+            src = self.aliases.get(src, src)
+            dst = self.aliases.get(dst, dst)
+
+        ret = '%-18s %-18s [ %s -> %s ]' % (
+            pkt['timestamp'], pkt['of-msg'], src, dst)
+        if self.detail and pkt['of-data']:
+            for data in pkt['of-data'].split(','):
+                data = data.strip()
+                if data:
+                    ret += (sep + data)
+        return ret
+
+    def prn(self, x):
+        print x
+
+    def tcpdump_open(self):
+        tcpdump_cmd = 'sudo /usr/local/sbin/tcpdump -i any \'%s\' %s'
+        tcpdump_args = '-l -nn -vv'
+        self.process = Popen(tcpdump_cmd % (self.tcpdump_filter, tcpdump_args),
+                        shell=True, bufsize=1, stdout=PIPE, stderr=STDOUT)
+        return self.process.stdout
+
+    def tcpdump_trace(self, fd):
+        # tcpdump decoder patterns
+        empty_line = compile('^$')
+        tcpdump_line = compile('^tcpdump.*$')
+        ip_line = compile('^(\d{2}\:\d{2}:\d{2}\.\d+) IP .*$')
+        tcp_line = compile('^\s*(\d+\.\d+\.\d+\.\d+)\.(\d+) \> (\d+\.\d+\.\d+\.\d+)\.(\d+)\:.*length \d+(.*)$')
+        of_hdr = compile('^([^ ]*) \(xid\=([^\)]*)\)\:(.*)$')
+        of_line = compile('^(.*in_port\=.*)$')
+        if_cont_line = compile('^\s+current\:')
+        inline_err = compile('^\s*\(\*\*\*.*$')
+        pkt_count = compile('^\d+ packets ')
+
+        # helper fn
+        def of_data(pkt, data):
+            if pkt['of-msg'] == 'packet_out':
+                data = data.replace(' ', ',')
+            pkt['of-data'] += (',' + data)
+
+        # decode packet data
+        line = fd.readline()
+        while line:
+            try:
+                line = line.strip()
+                pkt = self.pkt
+                if empty_line.match(line):
+                    pass
+                elif pkt_count.match(line):
+                    print>>stderr, line
+                elif tcpdump_line.match(line):
+                    pass
+                elif ip_line.match(line):
+                    if self.filter(): self.printer(self.fmt())
+                    self.pkt = defaultdict(str)
+                    self.reading_detail = False
+                    pkt = self.pkt
+                    pkt['timestamp'] = ip_line.match(line).groups()[0]
+                elif tcp_line.match(line):
+                    m =  tcp_line.match(line).groups()
+                    pkt['src-ip'] = m[0]
+                    pkt['src-port'] = m[1]
+                    pkt['dst-ip'] = m[2]
+                    pkt['dst-port'] = m[3]
+                    if of_hdr.match(m[4]):
+                        self.reading_detail = True
+                        m = of_hdr.match(m[4]).groups()
+                        pkt['of-msg'] = m[0].strip()
+                        pkt['of-xid'] = m[1]
+                        data = m[2]
+                        if not inline_err.match(m[2]):
+                            of_data(pkt, data)
+                        else:
+                            if DEBUG:
+                                print>>stderr, 'Inline Error', data
+                elif of_line.match(line):
+                    of_data(pkt, of_line.match(line).groups()[0])
+                elif if_cont_line.match(line):
+                    line = line.replace(',', '; ')
+                    of_data(pkt, '; '+line)
+                elif self.reading_detail:
+                    line = line.replace(',', '; ')
+                    of_data(pkt, line)
+                else:
+                    if DEBUG:
+                        print>>stderr, 'Unexpected: Line', line
+                line = fd.readline()
+            except KeyboardInterrupt:
+                print
+                if self.process:
+                    self.process.terminate()
+                    self.process = None
+                else:
+                    break
+
+def main():
+    usage = "usage: %prog [--detail] [--oneline] [--filter <tcpdump-filter>] [<msg-type> ...]"
+    optparser = OptionParser(usage=usage)
+    optparser.add_option("-f", "--filter", dest="tcpdump_filter",
+                         action="store", type="string", default='((tcp) and (port 6633))',
+                         help="tcpdump filter rule", metavar="FILTER")
+    optparser.add_option("-d", "--detail", dest="detail",
+                         action="store_true", default=False,
+                         help="print message detail")
+    optparser.add_option("-o", "--oneline", dest="oneline",
+                         action="store_true", default=False,
+                         help="print message detail on one line")
+    optparser.add_option("-a", "--alias", dest="alias",
+                         action="store_true", default=False,
+                         help="query controller to resolve address to switch-dpid/alias")
+    (options, msg_filters) = optparser.parse_args()
+
+    try:
+        print 'Starting openflow trace, use ^C to quit'
+        fmt = OpenFlowTracer.SUMMARY
+        if options.detail:  fmt = OpenFlowTracer.DETAIL
+        if options.oneline:  fmt = OpenFlowTracer.ONELINE
+        tracer = OpenFlowTracer(msg_filters, options.tcpdump_filter, fmt=fmt, alias=options.alias)
+        tracer.run()
+    except KeyboardInterrupt:
+        pass
+
+if __name__ == '__main__':
+    main()