diff --git a/python/cli/utils.py b/python/cli/utils.py
new file mode 100644
index 0000000..38e5ee2
--- /dev/null
+++ b/python/cli/utils.py
@@ -0,0 +1,186 @@
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+#
+
+import sys
+
+from google.protobuf.json_format import MessageToDict
+from termcolor import cprint, colored
+
+from table import TablePrinter
+
+
+_printfn = lambda l: sys.stdout.write(l + '\n')
+
+
+def pb2dict(pb_msg):
+    d = MessageToDict(pb_msg, including_default_value_fields=1,
+                      preserving_proto_field_name=1)
+    return d
+
+
+def p_cookie(cookie):
+    cookie =  '%x' % int(cookie)
+    if len(cookie) > 8:
+        return '~' + cookie[len(cookie)-8:]
+    else:
+        return cookie
+
+'''
+    OFPP_NORMAL     = 0x7ffffffa;  /* Forward using non-OpenFlow pipeline. */
+    OFPP_FLOOD      = 0x7ffffffb;  /* Flood using non-OpenFlow pipeline. */
+    OFPP_ALL        = 0x7ffffffc;  /* All standard ports except input port. */
+    OFPP_CONTROLLER = 0x7ffffffd;  /* Send to controller. */
+    OFPP_LOCAL      = 0x7ffffffe;  /* Local openflow "port". */
+    OFPP_ANY        = 0x7fffffff;  /* Special value used in some requests when
+'''
+
+
+def p_port(port):
+    if port & 0x7fffffff == 0x7ffffffa:
+        return 'NORMAL'
+    elif port & 0x7fffffff == 0x7ffffffb:
+        return 'FLOOD'
+    elif port & 0x7fffffff == 0x7ffffffc:
+        return 'ALL'
+    elif port & 0x7fffffff == 0x7ffffffd:
+        return 'CONTROLLER'
+    elif port & 0x7fffffff == 0x7ffffffe:
+        return 'LOCAL'
+    elif port & 0x7fffffff == 0x7fffffff:
+        return 'ANY'
+    else:
+        return str(port)
+
+
+def p_vlan_vid(vlan_vid):
+    if vlan_vid == 0:
+        return 'untagged'
+    assert vlan_vid & 4096 == 4096
+    return str(vlan_vid - 4096)
+
+
+def p_ipv4(x):
+    return '.'.join(str(v) for v in [
+        (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff
+    ])
+
+
+field_printers = {
+    'IN_PORT': lambda f: (100, 'in_port', p_port(f['port'])),
+    'VLAN_VID': lambda f: (101, 'vlan_vid', p_vlan_vid(f['vlan_vid'])),
+    'VLAN_PCP': lambda f: (102, 'vlan_pcp', str(f['vlan_pcp'])),
+    'ETH_TYPE': lambda f: (103, 'eth_type', '%X' % f['eth_type']),
+    'IP_PROTO': lambda f: (104, 'ip_proto', str(f['ip_proto'])),
+    'IPV4_DST': lambda f: (105, 'ipv4_dst', p_ipv4(f['ipv4_dst'])),
+    'UDP_SRC': lambda f: (106, 'udp_src', str(f['udp_src'])),
+    'UDP_DST': lambda f: (107, 'udp_dst', str(f['udp_dst'])),
+    'TCP_SRC': lambda f: (108, 'tcp_src', str(f['tcp_src'])),
+    'TCP_DST': lambda f: (109, 'tcp_dst', str(f['tcp_dst'])),
+    'METADATA': lambda f: (110, 'metadata', str(f['table_metadata'])),
+}
+
+
+def p_field(field):
+    assert field['oxm_class'].endswith('OPENFLOW_BASIC')
+    ofb = field['ofb_field']
+    assert not ofb['has_mask']
+    type = ofb['type'][len('OFPXMT_OFB_'):]
+    weight, field_name, value = field_printers[type](ofb)
+    return 1000 + weight, 'set_' + field_name, value
+
+
+action_printers = {
+    'SET_FIELD': lambda a: p_field(a['set_field']['field']),
+    'POP_VLAN': lambda a: (2000, 'pop_vlan', 'Yes'),
+    'PUSH_VLAN': lambda a: (2001, 'push_vlan', '%x' % a['push']['ethertype']),
+    'GROUP': lambda a: (3000, 'group', p_port(a['group']['group_id'])),
+    'OUTPUT': lambda a: (4000, 'output', p_port(a['output']['port'])),
+}
+
+
+def print_flows(what, id, type, flows, groups, printfn=_printfn):
+
+    header = ''.join([
+        '{} '.format(what),
+        colored(id, color='green', attrs=['bold']),
+        ' (type: ',
+        colored(type, color='blue'),
+        ')'
+    ]) + '\nFlows ({}):'.format(len(flows))
+
+    table = TablePrinter()
+    for i, flow in enumerate(flows):
+
+        table.add_cell(i, 0, 'table_id', value=str(flow['table_id']))
+        table.add_cell(i, 1, 'priority', value=str(flow['priority']))
+        table.add_cell(i, 2, 'cookie', p_cookie(flow['cookie']))
+
+        assert flow['match']['type'] == 'OFPMT_OXM'
+        for field in flow['match']['oxm_fields']:
+            assert field['oxm_class'].endswith('OPENFLOW_BASIC')
+            ofb = field['ofb_field']
+            # see CORD-816 (https://jira.opencord.org/browse/CORD-816)
+            assert not ofb['has_mask'], 'masked match not handled yet'
+            type = ofb['type'][len('OFPXMT_OFB_'):]
+            table.add_cell(i, *field_printers[type](ofb))
+
+        for instruction in flow['instructions']:
+            itype = instruction['type']
+            if itype == 4:
+                for action in instruction['actions']['actions']:
+                    atype = action['type'][len('OFPAT_'):]
+                    table.add_cell(i, *action_printers[atype](action))
+            elif itype == 1:
+                table.add_cell(i, 10000, 'goto-table',
+                               instruction['goto_table']['table_id'])
+            elif itype == 5:
+                table.add_cell(i, 10000, 'clear-actions', [])
+            else:
+                raise NotImplementedError(
+                    'not handling instruction type {}'.format(itype))
+
+    table.print_table(header, printfn)
+
+
+def print_groups(what, id, type, groups, printfn=_printfn):
+    header = ''.join([
+        '{} '.format(what),
+        colored(id, color='green', attrs=['bold']),
+        ' (type: ',
+        colored(type, color='blue'),
+        ')'
+    ]) + '\nGroups ({}):'.format(len(groups))
+
+    table = TablePrinter()
+    for i, group in enumerate(groups):
+        output_ports = []
+        for bucket in group['desc']['buckets']:
+            for action in bucket['actions']:
+                if action['type'] == 'OFPAT_OUTPUT':
+                   output_ports.append(action['output']['port'])
+        table.add_cell(i, 0, 'group_id', value=str(group['desc']['group_id']))
+        table.add_cell(i, 1, 'buckets', value=str(dict(output=output_ports)))
+
+    table.print_table(header, printfn)
+
+def dict2line(d):
+    assert isinstance(d, dict)
+    return ', '.join('{}: {}'.format(k, v) for k, v in sorted(d.items()))
+
+def enum2name(msg_obj, enum_type, enum_value):
+    descriptor = msg_obj.DESCRIPTOR.enum_types_by_name[enum_type]
+    name = descriptor.values_by_number[enum_value].name
+    return name
