Merge remote-tracking branch 'origin/master' into bsn_det_vport

Conflicts:
	loxi_front_end/type_maps.py
	openflow_input/bsn_l2_table
diff --git a/Makefile b/Makefile
index fb75c08..ab834be 100644
--- a/Makefile
+++ b/Makefile
@@ -79,6 +79,7 @@
 
 check:
 	PYTHONPATH=. ./utest/test_parser.py
+	PYTHONPATH=. ./utest/test_frontend.py
 	PYTHONPATH=. ./utest/test_test_data.py
 
 check-py: python
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index 18686c4..84bc782 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -41,7 +41,6 @@
 
 import sys
 import of_g
-import loxi_front_end.oxm as oxm
 import loxi_front_end.match as match
 import c_code_gen
 
diff --git a/c_gen/c_type_maps.py b/c_gen/c_type_maps.py
index 578bf0a..6cbf7bc 100644
--- a/c_gen/c_type_maps.py
+++ b/c_gen/c_type_maps.py
@@ -32,7 +32,6 @@
 import of_g
 import sys
 from generic_utils import *
-import loxi_front_end.oxm as oxm
 import loxi_front_end.type_maps as type_maps
 
 
diff --git a/loxi_front_end/frontend.py b/loxi_front_end/frontend.py
new file mode 100644
index 0000000..ab98c26
--- /dev/null
+++ b/loxi_front_end/frontend.py
@@ -0,0 +1,82 @@
+# Copyright 2013, Big Switch Networks, Inc.
+#
+# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+# the following special exception:
+#
+# LOXI Exception
+#
+# As a special exception to the terms of the EPL, you may distribute libraries
+# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+# that copyright and licensing notices generated by LoxiGen are not altered or removed
+# from the LoxiGen Libraries and the notice provided below is (i) included in
+# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+# documentation for the LoxiGen Libraries, if distributed in binary form.
+#
+# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+#
+# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+# a copy of the EPL 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
+# EPL for the specific language governing permissions and limitations
+# under the EPL.
+
+import copy
+import of_g
+import loxi_front_end.type_maps as type_maps
+from loxi_ir import *
+
+class InputError(Exception):
+    pass
+
+def create_member(m_ast):
+    if m_ast[0] == 'pad':
+        return OFPadMember(length=m_ast[1])
+    elif m_ast[0] == 'type':
+        return OFTypeMember(name=m_ast[2], oftype=m_ast[1], value=m_ast[3])
+    elif m_ast[0] == 'data':
+        if m_ast[2] == 'length' or m_ast[2] == 'len': # Should be moved to parser
+            return OFLengthMember(name=m_ast[2], oftype=m_ast[1])
+        elif m_ast[2] == 'actions_len':
+            # HACK only usage so far
+            return OFFieldLengthMember(name=m_ast[2], oftype=m_ast[1], field_name='actions')
+        else:
+            return OFDataMember(name=m_ast[2], oftype=m_ast[1])
+
+def create_ofinput(ast):
+    """
+    Create an OFInput from an AST
+
+    @param ast An AST as returned by loxi_front_end.parser.parse
+
+    @returns An OFInput object
+    """
+
+    ofinput = OFInput(wire_versions=set(), classes=[], enums=[])
+
+    for decl_ast in ast:
+        if decl_ast[0] == 'struct':
+            members = [create_member(m_ast) for m_ast in decl_ast[2]]
+            ofclass = OFClass(name=decl_ast[1], members=members)
+            ofinput.classes.append(ofclass)
+        if decl_ast[0] == 'enum':
+            enum = OFEnum(name=decl_ast[1], values=[(x[0], x[1]) for x in decl_ast[2]])
+            ofinput.enums.append(enum)
+        elif decl_ast[0] == 'metadata':
+            if decl_ast[1] == 'version':
+                if decl_ast[2] == 'any':
+                    ofinput.wire_versions.update(of_g.wire_ver_map.keys())
+                elif int(decl_ast[2]) in of_g.supported_wire_protos:
+                    ofinput.wire_versions.add(int(decl_ast[2]))
+                else:
+                    raise InputError("Unrecognized wire protocol version %r" % decl_ast[2])
+                found_wire_version = True
+
+    if not ofinput.wire_versions:
+        raise InputError("Missing #version metadata")
+
+    return ofinput
diff --git a/loxi_front_end/match.py b/loxi_front_end/match.py
index 4ab3126..42c0a9e 100644
--- a/loxi_front_end/match.py
+++ b/loxi_front_end/match.py
@@ -32,7 +32,6 @@
 import sys
 import of_g
 from generic_utils import *
-import oxm
 import loxi_utils.loxi_utils as loxi_utils
 
 #
@@ -465,24 +464,32 @@
                 print "Key %s not found in match struct, v %s" % (key, match_v)
                 sys.exit(1)
 
-    # Check oxm list and the list above
-    for key in oxm.oxm_types:
+    # Generate list of OXM names from the unified classes
+    oxm_names = [x[7:] for x in of_g.unified.keys() if
+                 x.startswith('of_oxm_') and
+                 x.find('masked') < 0 and
+                 x.find('header') < 0]
+
+    # Check that all OXMs are in the match members
+    for key in oxm_names:
         if not key in of_match_members:
             if not (key.find("_masked") > 0):
-                debug("Key %s in oxm.oxm_types, not of_match_members" % key)
+                debug("Key %s in OXM, not of_match_members" % key)
                 sys.exit(1)
             if not key[:-7] in of_match_members:
-                debug("Key %s in oxm.oxm_types, but %s not in of_match_members"
+                debug("Key %s in OXM, but %s not in of_match_members"
                       % (key, key[:-7]))
                 sys.exit(1)
 
+    # Check that all match members are in the OXMs
     for key in of_match_members:
-        if not key in oxm.oxm_types:
-            debug("Key %s in of_match_members, not in oxm.oxm_types" % key)
+        if not key in oxm_names:
+            debug("Key %s in of_match_members, not in OXM" % key)
             sys.exit(1)
-        if of_match_members[key]["m_type"] != oxm.oxm_types[key]:
+        oxm_type = of_g.unified['of_oxm_%s' % key]['union']['value']['m_type']
+        if of_match_members[key]["m_type"] != oxm_type:
             debug("Type mismatch for key %s in oxm data: %s vs %s" %
-                  (key, of_match_members[key]["m_type"], oxm.oxm_types[key]))
+                  (key, of_match_members[key]["m_type"], oxm_type))
             sys.exit(1)
 
 
diff --git a/loxi_front_end/oxm.py b/loxi_front_end/oxm.py
deleted file mode 100644
index ba5c072..0000000
--- a/loxi_front_end/oxm.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# Copyright 2013, Big Switch Networks, Inc.
-#
-# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
-# the following special exception:
-#
-# LOXI Exception
-#
-# As a special exception to the terms of the EPL, you may distribute libraries
-# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
-# that copyright and licensing notices generated by LoxiGen are not altered or removed
-# from the LoxiGen Libraries and the notice provided below is (i) included in
-# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
-# documentation for the LoxiGen Libraries, if distributed in binary form.
-#
-# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
-#
-# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
-# a copy of the EPL 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
-# EPL for the specific language governing permissions and limitations
-# under the EPL.
-
-import of_g
-
-oxm_types = dict(
-    in_port               = "of_port_no_t",
-    in_port_masked        = "of_port_no_t",
-    in_phy_port           = "of_port_no_t",
-    in_phy_port_masked    = "of_port_no_t",
-    metadata              = "uint64_t",
-    metadata_masked       = "uint64_t",
-    eth_dst               = "of_mac_addr_t",
-    eth_dst_masked        = "of_mac_addr_t",
-    eth_src               = "of_mac_addr_t",
-    eth_src_masked        = "of_mac_addr_t",
-    eth_type              = "uint16_t",
-    eth_type_masked       = "uint16_t",
-    vlan_vid              = "uint16_t",
-    vlan_vid_masked       = "uint16_t",
-    vlan_pcp              = "uint8_t",
-    vlan_pcp_masked       = "uint8_t",
-    ip_dscp               = "uint8_t",
-    ip_dscp_masked        = "uint8_t",
-    ip_ecn                = "uint8_t",
-    ip_ecn_masked         = "uint8_t",
-    ip_proto              = "uint8_t",
-    ip_proto_masked       = "uint8_t",
-    ipv4_src              = "uint32_t",
-    ipv4_src_masked       = "uint32_t",
-    ipv4_dst              = "uint32_t",
-    ipv4_dst_masked       = "uint32_t",
-    tcp_src               = "uint16_t",
-    tcp_src_masked        = "uint16_t",
-    tcp_dst               = "uint16_t",
-    tcp_dst_masked        = "uint16_t",
-    udp_src               = "uint16_t",
-    udp_src_masked        = "uint16_t",
-    udp_dst               = "uint16_t",
-    udp_dst_masked        = "uint16_t",
-    sctp_src              = "uint16_t",
-    sctp_src_masked       = "uint16_t",
-    sctp_dst              = "uint16_t",
-    sctp_dst_masked       = "uint16_t",
-    icmpv4_type           = "uint8_t",
-    icmpv4_type_masked    = "uint8_t",
-    icmpv4_code           = "uint8_t",
-    icmpv4_code_masked    = "uint8_t",
-    arp_op                = "uint16_t",
-    arp_op_masked         = "uint16_t",
-    arp_spa               = "uint32_t",
-    arp_spa_masked        = "uint32_t",
-    arp_tpa               = "uint32_t",
-    arp_tpa_masked        = "uint32_t",
-    arp_sha               = "of_mac_addr_t",
-    arp_sha_masked        = "of_mac_addr_t",
-    arp_tha               = "of_mac_addr_t",
-    arp_tha_masked        = "of_mac_addr_t",
-    ipv6_src              = "of_ipv6_t",
-    ipv6_src_masked       = "of_ipv6_t",
-    ipv6_dst              = "of_ipv6_t",
-    ipv6_dst_masked       = "of_ipv6_t",
-    ipv6_flabel           = "uint32_t",
-    ipv6_flabel_masked    = "uint32_t",
-    icmpv6_type           = "uint8_t",
-    icmpv6_type_masked    = "uint8_t",
-    icmpv6_code           = "uint8_t",
-    icmpv6_code_masked    = "uint8_t",
-    ipv6_nd_target        = "of_ipv6_t",
-    ipv6_nd_target_masked = "of_ipv6_t",
-    ipv6_nd_sll           = "of_mac_addr_t",
-    ipv6_nd_sll_masked    = "of_mac_addr_t",
-    ipv6_nd_tll           = "of_mac_addr_t",
-    ipv6_nd_tll_masked    = "of_mac_addr_t",
-    mpls_label            = "uint32_t",
-    mpls_label_masked     = "uint32_t",
-    mpls_tc               = "uint8_t",
-    mpls_tc_masked        = "uint8_t"
-    # FIXME Add 1.3 oxm elts
-    )
-
-oxm_wire_type = dict(
-    in_port               = (0 << 1),
-    in_port_masked        = (0 << 1) + 1,
-    in_phy_port           = (1 << 1),
-    in_phy_port_masked    = (1 << 1) + 1,
-    metadata              = (2 << 1),
-    metadata_masked       = (2 << 1) + 1,
-    eth_dst               = (3 << 1),
-    eth_dst_masked        = (3 << 1) + 1,
-    eth_src               = (4 << 1),
-    eth_src_masked        = (4 << 1) + 1,
-    eth_type              = (5 << 1),
-    eth_type_masked       = (5 << 1) + 1,
-    vlan_vid              = (6 << 1),
-    vlan_vid_masked       = (6 << 1) + 1,
-    vlan_pcp              = (7 << 1),
-    vlan_pcp_masked       = (7 << 1) + 1,
-    ip_dscp               = (8 << 1),
-    ip_dscp_masked        = (8 << 1) + 1,
-    ip_ecn                = (9 << 1),
-    ip_ecn_masked         = (9 << 1) + 1,
-    ip_proto              = (10 << 1),
-    ip_proto_masked       = (10 << 1) + 1,
-    ipv4_src              = (11 << 1),
-    ipv4_src_masked       = (11 << 1) + 1,
-    ipv4_dst              = (12 << 1),
-    ipv4_dst_masked       = (12 << 1) + 1,
-    tcp_src               = (13 << 1),
-    tcp_src_masked        = (13 << 1) + 1,
-    tcp_dst               = (14 << 1),
-    tcp_dst_masked        = (14 << 1) + 1,
-    udp_src               = (15 << 1),
-    udp_src_masked        = (15 << 1) + 1,
-    udp_dst               = (16 << 1),
-    udp_dst_masked        = (16 << 1) + 1,
-    sctp_src              = (17 << 1),
-    sctp_src_masked       = (17 << 1) + 1,
-    sctp_dst              = (18 << 1),
-    sctp_dst_masked       = (18 << 1) + 1,
-    icmpv4_type           = (19 << 1),
-    icmpv4_type_masked    = (19 << 1) + 1,
-    icmpv4_code           = (20 << 1),
-    icmpv4_code_masked    = (20 << 1) + 1,
-    arp_op                = (21 << 1),
-    arp_op_masked         = (21 << 1) + 1,
-    arp_spa               = (22 << 1),
-    arp_spa_masked        = (22 << 1) + 1,
-    arp_tpa               = (23 << 1),
-    arp_tpa_masked        = (23 << 1) + 1,
-    arp_sha               = (24 << 1),
-    arp_sha_masked        = (24 << 1) + 1,
-    arp_tha               = (25 << 1),
-    arp_tha_masked        = (25 << 1) + 1,
-    ipv6_src              = (26 << 1),
-    ipv6_src_masked       = (26 << 1) + 1,
-    ipv6_dst              = (27 << 1),
-    ipv6_dst_masked       = (27 << 1) + 1,
-    ipv6_flabel           = (28 << 1),
-    ipv6_flabel_masked    = (28 << 1) + 1,
-    icmpv6_type           = (29 << 1),
-    icmpv6_type_masked    = (29 << 1) + 1,
-    icmpv6_code           = (30 << 1),
-    icmpv6_code_masked    = (30 << 1) + 1,
-    ipv6_nd_target        = (31 << 1),
-    ipv6_nd_target_masked = (31 << 1) + 1,
-    ipv6_nd_sll           = (32 << 1),
-    ipv6_nd_sll_masked    = (32 << 1) + 1,
-    ipv6_nd_tll           = (33 << 1),
-    ipv6_nd_tll_masked    = (33 << 1) + 1,
-    mpls_label            = (34 << 1),
-    mpls_label_masked     = (34 << 1) + 1,
-    mpls_tc               = (35 << 1),
-    mpls_tc_masked        = (35 << 1) + 1
-    # FIXME Add 1.3 oxm elts
-)
-
-def add_oxm_classes_1_2(classes, version):
-    """
-    Add the OXM classes to object passed.  This is a dictionary
-    indexed by class name whose value is an array of member objects.
-    """
-    # First the parent class:
-    if version not in [of_g.VERSION_1_2, of_g.VERSION_1_3]:
-        return
-
-    members = []
-    classes["of_oxm"] = []
-    of_g.ordered_classes[version].append("of_oxm")
-    members.append(dict(name="type_len", m_type="uint32_t"))
-    classes["of_oxm_header"] = members
-    of_g.ordered_classes[version].append("of_oxm_header")
-
-    for oxm in oxm_types:
-        members = []
-        # Assert oxm_types[oxm] in of_base_types
-        m_type = oxm_types[oxm]
-        if m_type in of_g.of_mixed_types:
-            m_type = of_g.of_mixed_types[m_type][version]
-        # m_name = "value_" + of_g.of_base_types[m_type]["short_name"]
-        members.append(dict(name="type_len", m_type="uint32_t"))
-        # members.append(dict(name=m_name, m_type=oxm_types[oxm]))
-        members.append(dict(name="value", m_type=oxm_types[oxm]))
-        if oxm.find("_masked") > 0:
-            members.append(dict(name="value_mask", m_type=oxm_types[oxm]))
-
-        name = "of_oxm_" + oxm
-        of_g.ordered_classes[version].append(name)
-        classes[name] = members
-
-# /* Header for OXM experimenter match fields. */
-# struct ofp_oxm_experimenter_header {
-#     uint32_t oxm_header;        /* oxm_class = OFPXMC_EXPERIMENTER */
-#     uint32_t experimenter;      /* Experimenter ID which takes the same
-#                                    form as in struct ofp_experimenter_header. */
-# };
-
-
-# enum ofp_vlan_id {
-#     OFPVID_PRESENT = 0x1000,
-#     OFPVID_NONE    = 0x0000,
-# };
-
-# #define OFP_VLAN_NONE      OFPVID_NONE
diff --git a/loxi_front_end/parser.py b/loxi_front_end/parser.py
index d79dd3c..503a05a 100644
--- a/loxi_front_end/parser.py
+++ b/loxi_front_end/parser.py
@@ -50,9 +50,12 @@
 any_type = (array_type | list_type | scalar_type).setName("type name")
 
 # Structs
-struct_member = P.Group(any_type - identifier - s(';'))
+pad_member = P.Group(kw('pad') - s('(') - integer - s(')'))
+type_member = P.Group(tag('type') + any_type + identifier + s('==') + integer)
+data_member = P.Group(tag('data') + any_type - identifier)
+struct_member = pad_member | type_member | data_member;
 struct = kw('struct') - identifier - s('{') + \
-         P.Group(P.ZeroOrMore(struct_member)) + \
+         P.Group(P.ZeroOrMore(struct_member - s(';'))) + \
          s('}') - s(';')
 
 # Enums
@@ -71,4 +74,11 @@
 grammar.ignore(P.cppStyleComment)
 
 def parse(src):
-    return grammar.parseString(src, parseAll=True)
+    """
+    Given an input string, return the AST.
+
+    The AST is a low-level representation of the input. It changes frequently
+    with the input file syntax. The frontend.py module transforms the AST
+    into the OFInput represntation.
+    """
+    return grammar.parseString(src, parseAll=True).asList()
diff --git a/loxi_front_end/type_maps.py b/loxi_front_end/type_maps.py
index 0289833..1b30c1f 100644
--- a/loxi_front_end/type_maps.py
+++ b/loxi_front_end/type_maps.py
@@ -36,7 +36,6 @@
 import of_g
 import sys
 from generic_utils import *
-import oxm
 import loxi_utils.loxi_utils as loxi_utils
 
 invalid_type = "invalid_type"
@@ -54,148 +53,23 @@
 ################################################################
 
 instruction_types = {
-    # version 1.0
     of_g.VERSION_1_0:dict(),
-
-    # version 1.1
-    of_g.VERSION_1_1:dict(
-        goto_table = 1,
-        write_metadata = 2,
-        write_actions = 3,
-        apply_actions = 4,
-        clear_actions = 5,
-        experimenter = 0xffff
-        ),
-
-    # version 1.2
-    of_g.VERSION_1_2:dict(
-        goto_table = 1,
-        write_metadata = 2,
-        write_actions = 3,
-        apply_actions = 4,
-        clear_actions = 5,
-        experimenter = 0xffff
-        ),
-
-    # version 1.3
-    of_g.VERSION_1_3:dict(
-        goto_table = 1,
-        write_metadata = 2,
-        write_actions = 3,
-        apply_actions = 4,
-        clear_actions = 5,
-        meter = 6,
-        experimenter = 0xffff
-        )
+    of_g.VERSION_1_1:dict(),
+    of_g.VERSION_1_2:dict(),
+    of_g.VERSION_1_3:dict()
     }
 
-of_1_3_action_types = dict(
-    output       = 0,
-    copy_ttl_out = 11,
-    copy_ttl_in  = 12,
-    set_mpls_ttl = 15,
-    dec_mpls_ttl = 16,
-    push_vlan    = 17,
-    pop_vlan     = 18,
-    push_mpls    = 19,
-    pop_mpls     = 20,
-    set_queue    = 21,
-    group        = 22,
-    set_nw_ttl   = 23,
-    dec_nw_ttl   = 24,
-    set_field    = 25,
-    push_pbb     = 26,
-    pop_pbb      = 27,
-    experimenter = 0xffff,
-    bsn_mirror = 0xffff,
-    bsn_set_tunnel_dst = 0xffff,
-    nicira_dec_ttl = 0xffff
-    )
+# HACK shared between actions and action_ids
+of_1_3_action_types = dict()
 
-# Indexed by OF version
 action_types = {
-    # version 1.0
-    of_g.VERSION_1_0:dict(
-        output = 0,
-        set_vlan_vid = 1,
-        set_vlan_pcp = 2,
-        strip_vlan = 3,
-        set_dl_src = 4,
-        set_dl_dst = 5,
-        set_nw_src = 6,
-        set_nw_dst = 7,
-        set_nw_tos = 8,
-        set_tp_src = 9,
-        set_tp_dst = 10,
-        enqueue = 11,
-        experimenter = 0xffff,
-        bsn_mirror = 0xffff,
-        bsn_set_tunnel_dst = 0xffff,
-        nicira_dec_ttl = 0xffff
-        ),
-
-    # version 1.1
-    of_g.VERSION_1_1:dict(
-        output = 0,
-        set_vlan_vid = 1,
-        set_vlan_pcp = 2,
-        set_dl_src = 3,
-        set_dl_dst = 4,
-        set_nw_src = 5,
-        set_nw_dst = 6,
-        set_nw_tos = 7,
-        set_nw_ecn = 8,
-        set_tp_src = 9,
-        set_tp_dst = 10,
-        copy_ttl_out = 11,
-        copy_ttl_in = 12,
-        set_mpls_label = 13,
-        set_mpls_tc = 14,
-        set_mpls_ttl = 15,
-        dec_mpls_ttl = 16,
-        push_vlan = 17,
-        pop_vlan = 18,
-        push_mpls = 19,
-        pop_mpls = 20,
-        set_queue = 21,
-        group = 22,
-        set_nw_ttl = 23,
-        dec_nw_ttl = 24,
-        experimenter = 0xffff,
-        bsn_mirror = 0xffff,
-        bsn_set_tunnel_dst = 0xffff,
-        nicira_dec_ttl = 0xffff
-        ),
-
-    # version 1.2
-    of_g.VERSION_1_2:dict(
-        output       = 0,
-        copy_ttl_out = 11,
-        copy_ttl_in  = 12,
-        set_mpls_ttl = 15,
-        dec_mpls_ttl = 16,
-        push_vlan    = 17,
-        pop_vlan     = 18,
-        push_mpls    = 19,
-        pop_mpls     = 20,
-        set_queue    = 21,
-        group        = 22,
-        set_nw_ttl   = 23,
-        dec_nw_ttl   = 24,
-        set_field    = 25,
-        experimenter = 0xffff,
-        bsn_mirror = 0xffff,
-        bsn_set_tunnel_dst = 0xffff,
-        nicira_dec_ttl = 0xffff
-        ),
-
-    # version 1.3
+    of_g.VERSION_1_0:dict(),
+    of_g.VERSION_1_1:dict(),
+    of_g.VERSION_1_2:dict(),
     of_g.VERSION_1_3:of_1_3_action_types
-
     }
 
 action_id_types = {
-    # version 1.0
     of_g.VERSION_1_0:dict(),
     of_g.VERSION_1_1:dict(),
     of_g.VERSION_1_2:dict(),
@@ -203,28 +77,10 @@
     }
 
 queue_prop_types = {
-    # version 1.0
-    of_g.VERSION_1_0:dict(
-        min_rate      = 1,
-        # experimenter  = 0xffff
-        ),
-    # version 1.1
-    of_g.VERSION_1_1:dict(
-        min_rate      = 1,
-        #  experimenter  = 0xffff
-        ),
-    # version 1.2
-    of_g.VERSION_1_2:dict(
-        min_rate      = 1,
-        max_rate      = 2,
-        experimenter  = 0xffff
-        ),
-    # version 1.3
-    of_g.VERSION_1_3:dict(
-        min_rate      = 1,
-        max_rate      = 2,
-        experimenter  = 0xffff
-        )
+    of_g.VERSION_1_0:dict(),
+    of_g.VERSION_1_1:dict(),
+    of_g.VERSION_1_2:dict(),
+    of_g.VERSION_1_3:dict()
     }
 
 bsn_vport_types = {
@@ -247,83 +103,31 @@
     }
 
 oxm_types = {
-    # version 1.0
     of_g.VERSION_1_0:dict(),
-
-    # version 1.1
     of_g.VERSION_1_1:dict(),
-
-    # version 1.2
-    of_g.VERSION_1_2:oxm.oxm_wire_type,
-
-    # version 1.3
-    of_g.VERSION_1_3:oxm.oxm_wire_type  # FIXME needs update for 1.3?
+    of_g.VERSION_1_2:dict(),
+    of_g.VERSION_1_3:dict(),
     }
 
 hello_elem_types = {
-    # version 1.0
     of_g.VERSION_1_0:dict(),
-
-    # version 1.1
     of_g.VERSION_1_1:dict(),
-
-    # version 1.2
     of_g.VERSION_1_2:dict(),
-
-    # version 1.3
-    of_g.VERSION_1_3:dict(
-        versionbitmap = 1
-        )
+    of_g.VERSION_1_3:dict(),
     }
 
 table_feature_prop_types = {
-    # version 1.0
     of_g.VERSION_1_0:dict(),
-
-    # version 1.1
     of_g.VERSION_1_1:dict(),
-
-    # version 1.2
     of_g.VERSION_1_2:dict(),
-
-    # version 1.3
-    of_g.VERSION_1_3:dict(
-        instructions           = 0,
-        instructions_miss      = 1,
-        next_tables            = 2,
-        next_tables_miss       = 3,
-        write_actions          = 4,
-        write_actions_miss     = 5,
-        apply_actions          = 6,
-        apply_actions_miss     = 7,
-        match                  = 8,
-        wildcards              = 10,
-        write_setfield         = 12,
-        write_setfield_miss    = 13,
-        apply_setfield         = 14,
-        apply_setfield_miss    = 15,
-#        experimenter           = 0xFFFE,
-#        experimenter_miss      = 0xFFFF,
-        experimenter            = 0xFFFF,  # Wrong: should be experimenter_miss
-        )
+    of_g.VERSION_1_3:dict(),
     }
 
 meter_band_types = {
-    # version 1.0
     of_g.VERSION_1_0:dict(),
-
-    # version 1.1
     of_g.VERSION_1_1:dict(),
-
-    # version 1.2
     of_g.VERSION_1_2:dict(),
-
-    # version 1.3
-    of_g.VERSION_1_3:dict(
-        drop                   = 1,
-        dscp_remark            = 2,
-        experimenter           = 0xFFFF,
-        )
+    of_g.VERSION_1_3:dict(),
     }
 
 # All inheritance data for non-messages
@@ -340,35 +144,6 @@
     of_bsn_vport = bsn_vport_types
     )
 
-################################################################
-# Now generate the maps from parent to list of subclasses
-################################################################
-
-# # These lists have entries which are a fixed type, no inheritance
-# fixed_lists = [
-#     "of_list_bucket",
-#     "of_list_bucket_counter",
-#     "of_list_flow_stats_entry",
-#     "of_list_group_desc_stats_entry",
-#     "of_list_group_stats_entry",
-#     "of_list_packet_queue",
-#     "of_list_port_desc",
-#     "of_list_port_stats_entry",
-#     "of_list_queue_stats_entry",
-#     "of_list_table_stats_entry"
-#     ]
-
-# for cls in fixed_lists:
-#     base_type = list_to_entry_type(cls)
-#     of_g.inheritance_map[base_type] = [base_type]
-
-inheritance_map = dict()
-for parent, versioned in inheritance_data.items():
-    inheritance_map[parent] = set()
-    for ver, subclasses in versioned.items():
-        for subcls in subclasses:
-            inheritance_map[parent].add(subcls)
-
 def class_is_virtual(cls):
     """
     Returns True if cls is a virtual class
@@ -387,124 +162,34 @@
 #
 ################################################################
 
+# The hardcoded message types are for objects without proper inheritance
 message_types = {
     # version 1.0
     of_g.VERSION_1_0:dict(
-        hello                   = 0,
-        error_msg               = 1,
-        echo_request            = 2,
-        echo_reply              = 3,
-        experimenter            = 4,
-        features_request        = 5,
-        features_reply          = 6,
-        get_config_request      = 7,
-        get_config_reply        = 8,
-        set_config              = 9,
-        packet_in               = 10,
-        flow_removed            = 11,
-        port_status             = 12,
-        packet_out              = 13,
         flow_mod                = 14,
-        port_mod                = 15,
         stats_request           = 16,
         stats_reply             = 17,
-        barrier_request         = 18,
-        barrier_reply           = 19,
-        queue_get_config_request = 20,
-        queue_get_config_reply  = 21,
-        table_mod               = 22    # Unofficial 1.0 extension
         ),
 
     # version 1.1
     of_g.VERSION_1_1:dict(
-        hello                   = 0,
-        error_msg               = 1,
-        echo_request            = 2,
-        echo_reply              = 3,
-        experimenter            = 4,
-        features_request        = 5,
-        features_reply          = 6,
-        get_config_request      = 7,
-        get_config_reply        = 8,
-        set_config              = 9,
-        packet_in               = 10,
-        flow_removed            = 11,
-        port_status             = 12,
-        packet_out              = 13,
         flow_mod                = 14,
-        group_mod               = 15,
-        port_mod                = 16,
-        table_mod               = 17,
         stats_request           = 18,
         stats_reply             = 19,
-        barrier_request         = 20,
-        barrier_reply           = 21,
-        queue_get_config_request = 22,
-        queue_get_config_reply  = 23
         ),
 
     # version 1.2
     of_g.VERSION_1_2:dict(
-        hello                   = 0,
-        error_msg               = 1,
-        echo_request            = 2,
-        echo_reply              = 3,
-        experimenter            = 4,
-        features_request        = 5,
-        features_reply          = 6,
-        get_config_request      = 7,
-        get_config_reply        = 8,
-        set_config              = 9,
-        packet_in               = 10,
-        flow_removed            = 11,
-        port_status             = 12,
-        packet_out              = 13,
         flow_mod                = 14,
-        group_mod               = 15,
-        port_mod                = 16,
-        table_mod               = 17,
         stats_request           = 18,
         stats_reply             = 19,
-        barrier_request         = 20,
-        barrier_reply           = 21,
-        queue_get_config_request = 22,
-        queue_get_config_reply   = 23,
-        role_request            = 24,
-        role_reply              = 25,
         ),
 
     # version 1.3
     of_g.VERSION_1_3:dict(
-        hello                   = 0,
-        error_msg               = 1,
-        echo_request            = 2,
-        echo_reply              = 3,
-        experimenter            = 4,
-        features_request        = 5,
-        features_reply          = 6,
-        get_config_request      = 7,
-        get_config_reply        = 8,
-        set_config              = 9,
-        packet_in               = 10,
-        flow_removed            = 11,
-        port_status             = 12,
-        packet_out              = 13,
         flow_mod                = 14,
-        group_mod               = 15,
-        port_mod                = 16,
-        table_mod               = 17,
         stats_request           = 18,  # FIXME Multipart
         stats_reply             = 19,
-        barrier_request         = 20,
-        barrier_reply           = 21,
-        queue_get_config_request = 22,
-        queue_get_config_reply   = 23,
-        role_request            = 24,
-        role_reply              = 25,
-        async_get_request       = 26,
-        async_get_reply         = 27,
-        async_set               = 28,
-        meter_mod               = 29
         )
     }
 
@@ -674,21 +359,29 @@
 ################################################################
 
 type_val = dict()
+inheritance_map = dict()
 
-for version, classes in message_types.items():
-    for cls in classes:
-        name = "of_" + cls
-        type_val[(name, version)] = classes[cls]
+def generate_maps():
+    for parent, versioned in inheritance_data.items():
+        inheritance_map[parent] = set()
+        for ver, subclasses in versioned.items():
+            for subcls in subclasses:
+                inheritance_map[parent].add(subcls)
 
-for parent, versioned in inheritance_data.items():
-    for version, subclasses in versioned.items():
-        for subcls, value in subclasses.items():
-            name = parent + "_" + subcls
-            type_val[(name, version)] = value
+    for version, classes in message_types.items():
+        for cls in classes:
+            name = "of_" + cls
+            type_val[(name, version)] = classes[cls]
 
-# Special case OF-1.2 match type
-type_val[("of_match_v3", of_g.VERSION_1_2)] = 0x8000
-type_val[("of_match_v3", of_g.VERSION_1_3)] = 0x8000
+    for parent, versioned in inheritance_data.items():
+        for version, subclasses in versioned.items():
+            for subcls, value in subclasses.items():
+                name = parent + "_" + subcls
+                type_val[(name, version)] = value
+
+    # Special case OF-1.2 match type
+    type_val[("of_match_v3", of_g.VERSION_1_2)] = 0x8000
+    type_val[("of_match_v3", of_g.VERSION_1_3)] = 0x8000
 
 # Utility function
 def dict_to_array(d, m_val, def_val=-1):
@@ -805,92 +498,20 @@
     # version 1.0
     of_g.VERSION_1_0:dict(  # Version 1.0 extensions
         bsn = {   # BSN extensions; indexed by class name, value is subtype
-            "of_bsn_set_ip_mask"                     : 0,
-            "of_bsn_get_ip_mask_request"             : 1,
-            "of_bsn_get_ip_mask_reply"               : 2,
-            "of_bsn_set_mirroring"                   : 3,
-            "of_bsn_get_mirroring_request"           : 4,
-            "of_bsn_get_mirroring_reply"             : 5,
-            "of_bsn_shell_command"                   : 6,
-            "of_bsn_shell_output"                    : 7,
-            "of_bsn_shell_status"                    : 8,
-            "of_bsn_get_interfaces_request"          : 9,
-            "of_bsn_get_interfaces_reply"            : 10,
-            "of_bsn_set_pktin_suppression"           : 11,
-            "of_bsn_set_l2_table_request"            : 12,
-            "of_bsn_get_l2_table_request"            : 13,
-            "of_bsn_get_l2_table_reply"              : 14,
-            "of_bsn_virtual_port_create_request"     : 15,
-            "of_bsn_virtual_port_create_reply"       : 16,
-            "of_bsn_virtual_port_remove"             : 17,
-            "of_bsn_bw_enable_set_request"           : 18,
-            "of_bsn_bw_enable_get_request"           : 19,
-            "of_bsn_bw_enable_get_reply"             : 20,
-            "of_bsn_bw_clear_data_request"           : 21,
-            "of_bsn_bw_clear_data_reply"             : 22,
-            "of_bsn_bw_enable_set_reply"             : 23,
-            "of_bsn_set_l2_table_reply"              : 24,
             },
         nicira = {   # Nicira extensions, value is subtype
-            "of_nicira_controller_role_request"      : 10,
-            "of_nicira_controller_role_reply"        : 11,
             },
         ),
     of_g.VERSION_1_1:dict(  # Version 1.0 extensions
         bsn = {   # BSN extensions; indexed by class name, value is subtype
-            "of_bsn_set_mirroring"                   : 3,
-            "of_bsn_get_mirroring_request"           : 4,
-            "of_bsn_get_mirroring_reply"             : 5,
-            "of_bsn_get_interfaces_request"          : 9,
-            "of_bsn_get_interfaces_reply"            : 10,
-            "of_bsn_set_pktin_suppression"           : 11,
-            "of_bsn_virtual_port_create_request"     : 15,
-            "of_bsn_virtual_port_create_reply"       : 16,
-            "of_bsn_virtual_port_remove"             : 17,
-            "of_bsn_bw_enable_set_request"           : 18,
-            "of_bsn_bw_enable_get_request"           : 19,
-            "of_bsn_bw_enable_get_reply"             : 20,
-            "of_bsn_bw_clear_data_request"           : 21,
-            "of_bsn_bw_clear_data_reply"             : 22,
-            "of_bsn_bw_enable_set_reply"             : 23,
             },
         ),
     of_g.VERSION_1_2:dict(  # Version 1.0 extensions
         bsn = {   # BSN extensions; indexed by class name, value is subtype
-            "of_bsn_set_mirroring"                   : 3,
-            "of_bsn_get_mirroring_request"           : 4,
-            "of_bsn_get_mirroring_reply"             : 5,
-            "of_bsn_get_interfaces_request"          : 9,
-            "of_bsn_get_interfaces_reply"            : 10,
-            "of_bsn_set_pktin_suppression"           : 11,
-            "of_bsn_virtual_port_create_request"     : 15,
-            "of_bsn_virtual_port_create_reply"       : 16,
-            "of_bsn_virtual_port_remove"             : 17,
-            "of_bsn_bw_enable_set_request"           : 18,
-            "of_bsn_bw_enable_get_request"           : 19,
-            "of_bsn_bw_enable_get_reply"             : 20,
-            "of_bsn_bw_clear_data_request"           : 21,
-            "of_bsn_bw_clear_data_reply"             : 22,
-            "of_bsn_bw_enable_set_reply"             : 23,
             },
         ),
     of_g.VERSION_1_3:dict(  # Version 1.0 extensions
         bsn = {   # BSN extensions; indexed by class name, value is subtype
-            "of_bsn_set_mirroring"                   : 3,
-            "of_bsn_get_mirroring_request"           : 4,
-            "of_bsn_get_mirroring_reply"             : 5,
-            "of_bsn_get_interfaces_request"          : 9,
-            "of_bsn_get_interfaces_reply"            : 10,
-            "of_bsn_set_pktin_suppression"           : 11,
-            "of_bsn_virtual_port_create_request"     : 15,
-            "of_bsn_virtual_port_create_reply"       : 16,
-            "of_bsn_virtual_port_remove"             : 17,
-            "of_bsn_bw_enable_set_request"           : 18,
-            "of_bsn_bw_enable_get_request"           : 19,
-            "of_bsn_bw_enable_get_reply"             : 20,
-            "of_bsn_bw_clear_data_request"           : 21,
-            "of_bsn_bw_clear_data_reply"             : 22,
-            "of_bsn_bw_enable_set_reply"             : 23,
             },
         ),
 }
@@ -901,38 +522,26 @@
     # version 1.0
     of_g.VERSION_1_0:dict(  # Version 1.0 extensions
         bsn = {   # of_action_bsn_
-            "of_action_bsn_mirror"           : 1,
-            "of_action_bsn_set_tunnel_dst"   : 2,
             },
         nicira = {   # of_action_nicira_
-            "of_action_nicira_dec_ttl"       : 18,
             }
         ),
     of_g.VERSION_1_1:dict(  # Version 1.0 extensions
         bsn = {   # of_action_bsn_
-            "of_action_bsn_mirror"           : 1,
-            "of_action_bsn_set_tunnel_dst"   : 2,
             },
         nicira = {   # of_action_nicira_
-            "of_action_nicira_dec_ttl"       : 18,
             }
         ),
     of_g.VERSION_1_2:dict(  # Version 1.0 extensions
         bsn = {   # of_action_bsn_
-            "of_action_bsn_mirror"           : 1,
-            "of_action_bsn_set_tunnel_dst"   : 2,
             },
         nicira = {   # of_action_nicira_
-            "of_action_nicira_dec_ttl"       : 18,
             }
         ),
     of_g.VERSION_1_3:dict(  # Version 1.0 extensions
         bsn = {   # of_action_bsn_
-            "of_action_bsn_mirror"           : 1,
-            "of_action_bsn_set_tunnel_dst"   : 2,
             },
         nicira = {   # of_action_nicira_
-            "of_action_nicira_dec_ttl"       : 18,
             }
         ),
 }
@@ -946,11 +555,8 @@
     of_g.VERSION_1_2:dict(),
     of_g.VERSION_1_3:dict(  # Version 1.3 extensions
         bsn = {   # of_action_bsn_
-            "of_action_id_bsn_mirror"           : 1,
-            "of_action_id_bsn_set_tunnel_dst"   : 2,
             },
         nicira = {   # of_action_nicira_
-            "of_action_id_nicira_dec_ttl"       : 18,
             }
         ),
 }
diff --git a/loxi_ir.py b/loxi_ir.py
new file mode 100644
index 0000000..9a27272
--- /dev/null
+++ b/loxi_ir.py
@@ -0,0 +1,136 @@
+# Copyright 2013, Big Switch Networks, Inc.
+#
+# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+# the following special exception:
+#
+# LOXI Exception
+#
+# As a special exception to the terms of the EPL, you may distribute libraries
+# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+# that copyright and licensing notices generated by LoxiGen are not altered or removed
+# from the LoxiGen Libraries and the notice provided below is (i) included in
+# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+# documentation for the LoxiGen Libraries, if distributed in binary form.
+#
+# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+#
+# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+# a copy of the EPL 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
+# EPL for the specific language governing permissions and limitations
+# under the EPL.
+
+from collections import namedtuple
+
+# This module is intended to be imported like this: from loxi_ir import *
+# All public names are prefixed with 'OF'.
+__all__ = [
+    'OFInput',
+    'OFProtocol',
+    'OFClass',
+    'OFDataMember',
+    'OFTypeMember',
+    'OFLengthMember',
+    'OFFieldLengthMember',
+    'OFPadMember',
+    'OFEnum',
+]
+
+"""
+One input file
+
+@param wire_versions Set of integer wire versions this file applies to
+@param classes List of OFClass objects in the same order as in the file
+@param enums List of Enum objects in the same order as in the file
+"""
+OFInput = namedtuple('OFInput', ['wire_versions', 'classes', 'enums'])
+
+"""
+One version of the OpenFlow protocol
+
+Combination of multiple OFInput objects.
+
+@param wire_version
+@param classes List of OFClass objects
+@param enums List of Enum objects
+"""
+OFProtocol = namedtuple('OFProtocol', ['wire_version', 'classes', 'enums'])
+
+"""
+An OpenFlow class
+
+All compound objects like messages, actions, instructions, etc are
+uniformly represented by this class.
+
+The members are in the same order as on the wire.
+
+@param name
+@param members List of *Member objects
+"""
+OFClass = namedtuple('OFClass', ['name', 'members'])
+
+"""
+Normal field
+
+@param name
+@param oftype C-like type string
+
+Example: packet_in.buffer_id
+"""
+OFDataMember = namedtuple('OFDataMember', ['name', 'oftype'])
+
+"""
+Field used to determine the type of an OpenFlow object
+
+@param name
+@param oftype C-like type string
+@param value Fixed type value
+
+Example: packet_in.type, flow_add._command
+"""
+OFTypeMember = namedtuple('OFTypeMember', ['name', 'oftype', 'value'])
+
+"""
+Field with the length of the containing object
+
+@param name
+@param oftype C-like type string
+
+Example: packet_in.length, action_output.len
+"""
+OFLengthMember = namedtuple('OFLengthMember', ['name', 'oftype'])
+
+"""
+Field with the length of another field in the containing object
+
+@param name
+@param oftype C-like type string
+@param field_name Peer field whose length this field contains
+
+Example: packet_out.actions_len (only usage)
+"""
+OFFieldLengthMember = namedtuple('OFFieldLengthMember', ['name', 'oftype', 'field_name'])
+
+"""
+Zero-filled padding
+
+@param length Length in bytes
+
+Example: packet_in.pad
+"""
+OFPadMember = namedtuple('OFPadMember', ['length'])
+
+"""
+An OpenFlow enumeration
+
+All values are Python ints.
+
+@param name
+@param values List of (name, value) tuples in input order
+"""
+OFEnum = namedtuple('OFEnum', ['name', 'values'])
diff --git a/loxigen.py b/loxigen.py
index f30efec..bfa4909 100755
--- a/loxigen.py
+++ b/loxigen.py
@@ -76,8 +76,8 @@
 import os
 import glob
 import copy
+import collections
 import of_g
-import loxi_front_end.oxm as oxm
 import loxi_front_end.type_maps as type_maps
 import loxi_utils.loxi_utils as loxi_utils
 import loxi_front_end.c_parse_utils as c_parse_utils
@@ -85,7 +85,8 @@
 import pyparsing
 import loxi_front_end.parser as parser
 import loxi_front_end.translation as translation
-
+import loxi_front_end.frontend as frontend
+from loxi_ir import *
 from generic_utils import *
 
 root_dir = os.path.dirname(os.path.realpath(__file__))
@@ -314,51 +315,26 @@
     """
     Process an input file
 
+    Does not modify global state.
+
     @param filename The input filename
 
-    @returns (wire_version, classes), where wire_version is the integer wire
-    protocol number and classes is the dict of all classes processed from the
-    file.
+    @returns An OFInput object
     """
 
     # Parse the input file
     try:
-        ast = parser.parse(open(filename, 'r').read())
+        with open(filename, 'r') as f:
+            ast = parser.parse(f.read())
     except pyparsing.ParseBaseException as e:
         print "Parse error in %s: %s" % (os.path.basename(filename), str(e))
         sys.exit(1)
 
-    ofinput = of_g.OFInput()
-
-    # Now for each structure, generate lists for each member
-    for s in ast:
-        if s[0] == 'struct':
-            name = s[1].replace("ofp_", "of_", 1)
-            members = [dict(m_type=x[0], name=x[1]) for x in s[2]]
-            ofinput.classes[name] = members
-            ofinput.ordered_classes.append(name)
-            if name in type_maps.inheritance_map:
-                # Clone class into header class and add to list
-                ofinput.classes[name + "_header"] = members[:]
-                ofinput.ordered_classes.append(name + "_header")
-        if s[0] == 'enum':
-            name = s[1]
-            members = s[2]
-            ofinput.enums[name] = [(x[0], x[1]) for x in members]
-        elif s[0] == 'metadata':
-            if s[1] == 'version':
-                log("Found version: wire version " + s[2])
-                if s[2] == 'any':
-                    ofinput.wire_versions.update(of_g.wire_ver_map.keys())
-                elif int(s[2]) in of_g.supported_wire_protos:
-                    ofinput.wire_versions.add(int(s[2]))
-                else:
-                    debug("Unrecognized wire protocol version")
-                    sys.exit(1)
-                found_wire_version = True
-
-    if not ofinput.wire_versions:
-        debug("Missing #version metadata")
+    # Create the OFInput from the AST
+    try:
+        ofinput = frontend.create_ofinput(ast)
+    except frontend.InputError as e:
+        print "Error in %s: %s" % (os.path.basename(filename), str(e))
         sys.exit(1)
 
     return ofinput
@@ -439,6 +415,7 @@
     @fixme Should select versions to support from command line
     """
 
+    ofinputs_by_version = collections.defaultdict(lambda: [])
     filenames = sorted(glob.glob("%s/openflow_input/*" % root_dir))
 
     # Ignore emacs backup files
@@ -450,26 +427,107 @@
 
         # Populate global state
         for wire_version in ofinput.wire_versions:
+            ofinputs_by_version[wire_version].append(ofinput)
             version_name = of_g.of_version_wire2name[wire_version]
-            versions[version_name]['classes'].update(copy.deepcopy(ofinput.classes))
-            of_g.ordered_classes[wire_version].extend(ofinput.ordered_classes)
 
-            for enum_name, members in ofinput.enums.items():
-                for member_name, value in members:
+            for ofclass in ofinput.classes:
+                of_g.ordered_classes[wire_version].append(ofclass.name)
+                legacy_members = []
+                pad_count = 0
+                for m in ofclass.members:
+                    if type(m) == OFPadMember:
+                        m_name = 'pad%d' % pad_count
+                        if m_name == 'pad0': m_name = 'pad'
+                        legacy_members.append(dict(m_type='uint8_t[%d]' % m.length,
+                                                   name=m_name))
+                        pad_count += 1
+                    else:
+                        legacy_members.append(dict(m_type=m.oftype, name=m.name))
+                versions[version_name]['classes'][ofclass.name] = legacy_members
+
+            for enum in ofinput.enums:
+                for name, value in enum.values:
                     identifiers.add_identifier(
-                        translation.loxi_name(member_name),
-                        member_name, enum_name, value, wire_version,
+                        translation.loxi_name(name),
+                        name, enum.name, value, wire_version,
                         of_g.identifiers, of_g.identifiers_by_group)
 
-def add_extra_classes():
+        for wire_version, ofinputs in ofinputs_by_version.items():
+            ofprotocol = OFProtocol(wire_version=wire_version, classes=[], enums=[])
+            for ofinput in ofinputs:
+                ofprotocol.classes.extend(ofinput.classes)
+                ofprotocol.enums.extend(ofinput.enums)
+            ofprotocol.classes.sort(key=lambda ofclass: ofclass.name)
+            of_g.ir[wire_version] = ofprotocol
+
+def populate_type_maps():
     """
-    Add classes that are generated by Python code instead of from the
-    input files.
+    Use the type members in the IR to fill out the legacy type_maps.
     """
 
-    for wire_version in [of_g.VERSION_1_2, of_g.VERSION_1_3]:
-        version_name = of_g.of_version_wire2name[wire_version]
-        oxm.add_oxm_classes_1_2(versions[version_name]['classes'], wire_version)
+    def split_inherited_cls(cls):
+        if cls == 'of_meter_band_stats': # HACK not a subtype of of_meter_band
+            return None, None
+        for parent in sorted(type_maps.inheritance_data.keys(), reverse=True):
+            if cls.startswith(parent):
+                return (parent, cls[len(parent)+1:])
+        return None, None
+
+    def find_experimenter(parent, cls):
+        for experimenter in sorted(of_g.experimenter_name_to_id.keys(), reverse=True):
+            prefix = parent + '_' + experimenter
+            if cls.startswith(prefix):
+                return experimenter
+        return None
+
+    def find_type_value(ofclass, m_name):
+        for m in ofclass.members:
+            if isinstance(m, OFTypeMember) and m.name == m_name:
+                return m.value
+        raise KeyError("ver=%d, cls=%s, m_name=%s" % (wire_version, cls, m_name))
+
+    # Most inheritance classes: actions, instructions, etc
+    for wire_version, protocol in of_g.ir.items():
+        for ofclass in protocol.classes:
+            cls = ofclass.name
+            parent, subcls = split_inherited_cls(cls)
+            if not (parent and subcls):
+                continue
+            if parent == 'of_oxm':
+                val = (find_type_value(ofclass, 'type_len') >> 8) & 0xff
+            else:
+                val = find_type_value(ofclass, 'type')
+            type_maps.inheritance_data[parent][wire_version][subcls] = val
+
+            # Extensions (only actions for now)
+            experimenter = find_experimenter(parent, cls)
+            if parent == 'of_action' and experimenter:
+                val = find_type_value(ofclass, 'subtype')
+                type_maps.extension_action_subtype[wire_version][experimenter][cls] = val
+                if wire_version >= of_g.VERSION_1_3:
+                    cls2 = parent + "_id" + cls[len(parent):]
+                    type_maps.extension_action_id_subtype[wire_version][experimenter][cls2] = val
+
+    # Messages
+    for wire_version, protocol in of_g.ir.items():
+        for ofclass in protocol.classes:
+            cls = ofclass.name
+            # HACK (though this is what loxi_utils.class_is_message() does)
+            if not [x for x in ofclass.members if isinstance(x, OFDataMember) and x.name == 'xid']:
+                continue
+            if cls == 'of_header':
+                continue
+            subcls = cls[3:]
+            val = find_type_value(ofclass, 'type')
+            type_maps.message_types[wire_version][subcls] = val
+
+            # Extensions
+            experimenter = find_experimenter('of', cls)
+            if experimenter:
+                val = find_type_value(ofclass, 'subtype')
+                type_maps.extension_message_subtype[wire_version][experimenter][cls] = val
+
+    type_maps.generate_maps()
 
 def analyze_input():
     """
@@ -477,6 +535,15 @@
     lengths of struct members and the set of list and action_id types.
     """
 
+    # Generate header classes for inheritance parents
+    for wire_version, ordered_classes in of_g.ordered_classes.items():
+        classes = versions[of_g.of_version_wire2name[wire_version]]['classes']
+        for cls in ordered_classes:
+            if cls in type_maps.inheritance_map:
+                new_cls = cls + '_header'
+                of_g.ordered_classes[wire_version].append(new_cls)
+                classes[new_cls] = classes[cls]
+
     # Generate action_id classes for OF 1.3
     for wire_version, ordered_classes in of_g.ordered_classes.items():
         if not wire_version in [of_g.VERSION_1_3]:
@@ -583,7 +650,7 @@
 
     initialize_versions()
     read_input()
-    add_extra_classes()
+    populate_type_maps()
     analyze_input()
     unify_input()
     order_and_assign_object_ids()
diff --git a/of_g.py b/of_g.py
index db040f1..bc9888f 100644
--- a/of_g.py
+++ b/of_g.py
@@ -350,6 +350,11 @@
     uint64_t metadata[(OF_OBJECT_METADATA_BYTES + 7) / 8];
 """
 
+# LOXI intermediate representation
+# This is a hash from wire versions to OFProtocol objects.
+# See loxi_ir.py
+
+ir = {}
 
 ##
 # LOXI identifiers
@@ -513,20 +518,3 @@
 
 loxigen_dbg_file = sys.stdout
 loxigen_log_file = sys.stdout
-
-################################################################
-#
-# Internal representation
-#
-################################################################
-
-class OFInput(object):
-    """
-    A single LOXI input file.
-    """
-
-    def __init__(self):
-        self.wire_versions = set()
-        self.classes = {}
-        self.ordered_classes = []
-        self.enums = {}
diff --git a/openflow_input/bsn_bw b/openflow_input/bsn_bw
index b6e0972..e0ff3e3 100644
--- a/openflow_input/bsn_bw
+++ b/openflow_input/bsn_bw
@@ -30,61 +30,61 @@
 
 #version any
 
-struct ofp_bsn_bw_enable_set_request {
+struct of_bsn_bw_enable_set_request {
     uint8_t version;
-    uint8_t type;           // OFPT_VENDOR
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_BW_ENABLE_SET
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 18;
     uint32_t enable;        // 0 to disable the extension, 1 to enable it
 };
 
-struct ofp_bsn_bw_enable_set_reply {
+struct of_bsn_bw_enable_set_reply {
     uint8_t version;
-    uint8_t type;           // OFPT_VENDOR
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_BW_ENABLE_SET
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 23;
     uint32_t enable;        // Resulting state, 0 disabled, 1 enabled
     uint32_t status;        // Result code: 0 success
 };
 
-struct ofp_bsn_bw_enable_get_request {
+struct of_bsn_bw_enable_get_request {
     uint8_t version;
-    uint8_t type;           // OFPT_VENDOR
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_BW_ENABLE_GET_REQUEST
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 19;
 };
 
-struct ofp_bsn_bw_enable_get_reply {
+struct of_bsn_bw_enable_get_reply {
     uint8_t version;
-    uint8_t type;           // OFPT_VENDOR
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_BW_ENABLE_GET_REQUEST
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 20;
     uint32_t enabled;       // 0 if feature is disabled; 1 if feature enabled
 };
 
-struct ofp_bsn_bw_clear_data_request {
+struct of_bsn_bw_clear_data_request {
     uint8_t version;
-    uint8_t type;           // OFPT_VENDOR
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_BW_CLEAR_DATA
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 21;
 };
 
-struct ofp_bsn_bw_clear_data_reply {
+struct of_bsn_bw_clear_data_reply {
     uint8_t version;
-    uint8_t type;           // OFPT_VENDOR
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_BW_CLEAR_DATA
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 22;
     uint32_t status;        // Result code, 0 success
 };
diff --git a/openflow_input/bsn_get_interfaces b/openflow_input/bsn_get_interfaces
index 90060ee..ba1508c 100644
--- a/openflow_input/bsn_get_interfaces
+++ b/openflow_input/bsn_get_interfaces
@@ -27,29 +27,29 @@
 
 #version any
 
-struct ofp_bsn_get_interfaces_request {
+struct of_bsn_get_interfaces_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_GET_INTERFACES_REQUEST
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 9;
 };
 
-struct ofp_bsn_interface {
+struct of_bsn_interface {
     of_mac_addr_t hw_addr;
-    uint16_t pad;
+    pad(2);
     of_port_name_t name;
     uint32_t ipv4_addr;
     uint32_t ipv4_netmask;
 };
 
-struct ofp_bsn_get_interfaces_reply {
+struct of_bsn_get_interfaces_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_GET_INTERFACES_REQUEST
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 10;
     list(of_bsn_interface_t) interfaces;
 };
diff --git a/openflow_input/bsn_ip_mask b/openflow_input/bsn_ip_mask
index 03f233b..b6d517b 100644
--- a/openflow_input/bsn_ip_mask
+++ b/openflow_input/bsn_ip_mask
@@ -27,37 +27,37 @@
 
 #version 1
 
-struct ofp_bsn_set_ip_mask {
+struct of_bsn_set_ip_mask {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // bsn 0x005c16c7,
-    uint32_t subtype;       // 0
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 0;
     uint8_t index;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t mask;
 };
 
-struct ofp_bsn_get_ip_mask_request {
+struct of_bsn_get_ip_mask_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // bsn 0x005c16c7,
-    uint32_t subtype;       // 1
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 1;
     uint8_t index;
-    uint8_t[7] pad;
+    pad(7);
 };
 
-struct ofp_bsn_get_ip_mask_reply {
+struct of_bsn_get_ip_mask_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // bsn 0x005c16c7,
-    uint32_t subtype;       // 2
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 2;
     uint8_t index;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t mask;
 };
diff --git a/openflow_input/bsn_l2_table b/openflow_input/bsn_l2_table
index 3795ea2..e3938a8 100644
--- a/openflow_input/bsn_l2_table
+++ b/openflow_input/bsn_l2_table
@@ -28,48 +28,48 @@
 #version 1
 
 // BSN L2 table configuration messages
-struct ofp_bsn_set_l2_table_request {
+struct of_bsn_set_l2_table_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN_REQUEST
-    uint32_t subtype;   // BSN_L2_TABLE_SET
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 12;
     uint8_t l2_table_enable;    // 1 == enabled, 0 == disabled
     uint8_t pad;
     uint16_t l2_table_priority;  // priority of all flows in L2 table
     uint8_t[4] pad;
 };
 
-struct ofp_bsn_set_l2_table_reply {
+struct of_bsn_set_l2_table_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_L2_TABLE_SET_REPLY
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 24;
     uint8_t l2_table_enable;    // Resulting state: 1 == enabled, 0 == disabled
     uint8_t pad;
     uint16_t l2_table_priority;  // priority used, must match request if ok
     uint32_t status; // 0 means success
 };
 
-struct ofp_bsn_get_l2_table_request {
+struct of_bsn_get_l2_table_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_L2_TABLE_GET_REQUEST
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 13;
 };
 
-struct ofp_bsn_get_l2_table_reply {
+struct of_bsn_get_l2_table_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_L2_TABLE_GET_REPLY
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 14;
     uint8_t l2_table_enable;    // 1 == enabled, 0 == disabled
     uint8_t pad;
     uint16_t l2_table_priority;  // priority of all flows in L2 table
diff --git a/openflow_input/bsn_mirror b/openflow_input/bsn_mirror
index c873595..cc9e4c3 100644
--- a/openflow_input/bsn_mirror
+++ b/openflow_input/bsn_mirror
@@ -28,47 +28,47 @@
 #version any
 
 // BSN mirror action
-struct ofp_action_bsn_mirror {
-    uint16_t type;      // OF_ACTION_TYPE_EXPERIMENTER
+struct of_action_bsn_mirror {
+    uint16_t type == 65535;
     uint16_t len;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN 
-    uint32_t subtype;   // ACTION_BSN_MIRROR 
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 1;
     uint32_t dest_port; // mirror destination port
     uint32_t vlan_tag;  // VLAN tag for mirrored packet (TPID+TCI) (0 == none)
     uint8_t copy_stage; // 0 == ingress, 1 == egress 
-    uint8_t[3] pad;
+    pad(3);
 };
 
 // BSN mirroring messages
-struct ofp_bsn_set_mirroring {
+struct of_bsn_set_mirroring {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_MIRRORING_SET
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 3;
     uint8_t report_mirror_ports;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_bsn_get_mirroring_request {
+struct of_bsn_get_mirroring_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_MIRRORING_GET_REQUEST
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 4;
     uint8_t report_mirror_ports;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_bsn_get_mirroring_reply {
+struct of_bsn_get_mirroring_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_MIRRORING_GET_REPLY
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 5;
     uint8_t report_mirror_ports;
-    uint8_t[3] pad;
+    pad(3);
 };
diff --git a/openflow_input/bsn_pktin_suppression b/openflow_input/bsn_pktin_suppression
index fcfa4aa..4dcf71d 100644
--- a/openflow_input/bsn_pktin_suppression
+++ b/openflow_input/bsn_pktin_suppression
@@ -55,15 +55,15 @@
 // The switch should reject the message if both 'hard_timeout' and 'idle_timeout'
 // are zero, since the suppression flows would never expire.
 
-struct ofp_bsn_set_pktin_suppression {
+struct of_bsn_set_pktin_suppression {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;         // 11
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 11;
     uint8_t enabled;
-    uint8_t pad;
+    pad(1);
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
diff --git a/openflow_input/bsn_set_tunnel_dst b/openflow_input/bsn_set_tunnel_dst
index 6b16d96..74757f6 100644
--- a/openflow_input/bsn_set_tunnel_dst
+++ b/openflow_input/bsn_set_tunnel_dst
@@ -28,10 +28,10 @@
 #version any
 
 // BSN set tunnel destination IP action
-struct ofp_action_bsn_set_tunnel_dst {
-    uint16_t type;      // OF_ACTION_TYPE_EXPERIMENTER
+struct of_action_bsn_set_tunnel_dst {
+    uint16_t type == 65535;
     uint16_t len;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN 
-    uint32_t subtype;   // ACTION_BSN_SET_TUNNEL_DST
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 2;
     uint32_t dst; // tunnel destination IP
 };
diff --git a/openflow_input/bsn_shell b/openflow_input/bsn_shell
index ea85571..805b7e9 100644
--- a/openflow_input/bsn_shell
+++ b/openflow_input/bsn_shell
@@ -27,33 +27,33 @@
 
 #version 1
 
-struct ofp_bsn_shell_command {
+struct of_bsn_shell_command {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_SHELL_COMMAND
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 6;
     uint32_t service;
     of_octets_t data;
 };
 
-struct ofp_bsn_shell_output {
+struct of_bsn_shell_output {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_SHELL_OUTPUT
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 7;
     of_octets_t data;
 };
 
-struct ofp_bsn_shell_status {
+struct of_bsn_shell_status {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;   // BSN_SHELL_STATUS
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 8;
     uint32_t status;
 };
diff --git a/openflow_input/bsn_table_mod b/openflow_input/bsn_table_mod
index 418c716..cc5e723 100644
--- a/openflow_input/bsn_table_mod
+++ b/openflow_input/bsn_table_mod
@@ -29,12 +29,12 @@
 
 // This is the 1.1+ table mod message which we back port to 1.0
 // for use inside components
-struct ofp_table_mod {
+struct of_table_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 22;
     uint16_t length;
     uint32_t xid;
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t config;
 };
diff --git a/openflow_input/bsn_vport b/openflow_input/bsn_vport
index af0b579..cb197dd 100644
--- a/openflow_input/bsn_vport
+++ b/openflow_input/bsn_vport
@@ -39,7 +39,7 @@
 
 // BSN Virtual port object header
 // FIXME For now, inheritance is not exercised.  See below.
-struct ofp_bsn_vport {
+struct of_bsn_vport {
     uint16_t type;  /* Discriminate virtual port type */
     uint16_t length; /* Length in bytes of this structure with this header */
     /* Remainder of data is specific to the port type */
@@ -49,7 +49,7 @@
 // Q-in-Q virtual port specification
 
 struct of_bsn_vport_q_in_q {
-    uint16_t type;    /* 0 */
+    uint16_t type == 0;
     uint16_t length;  /* 16 */
     uint32_t port_no;     /* OF port number of parent; usually phys port */
     uint16_t ingress_tpid;
@@ -59,13 +59,13 @@
 };
 
 // Request from controller to switch to create vport
-struct ofp_bsn_virtual_port_create_request {
+struct of_bsn_virtual_port_create_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_VIRTUAL_PORT_CREATE_REQUEST
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 15;
     // FIXME This should be an instance of the inheritance superclass
     of_bsn_vport_q_in_q_t vport;   // Description of vport to create
     // Additional data follows depending on header type
@@ -73,23 +73,23 @@
 
 // Reply from switch to controller indicating port number created
 // vport_no must be 16 bits to be compatible with 1.0
-struct ofp_bsn_virtual_port_create_reply {
+struct of_bsn_virtual_port_create_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;           // Must match create_request
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_VIRTUAL_PORT_CREATE_REPLY
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 16;
     uint32_t vport_no;      // The OF port number created.  16-bits for OF 1.0
 };
 
 // Request from controller to switch to remove a vport
-struct ofp_bsn_virtual_port_remove {
+struct of_bsn_virtual_port_remove {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter;  // OF_EXPERIMENTER_ID_BSN
-    uint32_t subtype;       // BSN_VIRTUAL_PORT_REMOVE
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 17;
     uint32_t vport_no;      // The OF port number to be removed
 };
diff --git a/openflow_input/nicira_dec_ttl b/openflow_input/nicira_dec_ttl
index b507d57..77649af 100644
--- a/openflow_input/nicira_dec_ttl
+++ b/openflow_input/nicira_dec_ttl
@@ -27,11 +27,11 @@
 
 #version any
 
-struct ofp_action_nicira_dec_ttl {
-    uint16_t type;      // OF_ACTION_TYPE_EXPERIMENTER
+struct of_action_nicira_dec_ttl {
+    uint16_t type == 65535;
     uint16_t len;
-    uint32_t experimenter;    // OF_EXPERIMENTER_ID_NICIRA
-    uint16_t subtype;         // 18
-    uint16_t pad;
-    uint32_t pad2;
+    uint32_t experimenter == 0x2320;
+    uint16_t subtype == 18;
+    pad(2);
+    pad(4);
 };
diff --git a/openflow_input/nicira_role b/openflow_input/nicira_role
index caa2c1a..5747d45 100644
--- a/openflow_input/nicira_role
+++ b/openflow_input/nicira_role
@@ -33,22 +33,22 @@
    NX_ROLE_SLAVE = 2,
 };
 
-struct ofp_nicira_controller_role_request {
+struct of_nicira_controller_role_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter; // OF_EXPERIMENTER_ID_NICIRA 0x00002320
-    uint32_t subtype;      // 10
+    uint32_t experimenter == 0x2320;
+    uint32_t subtype == 10;
     uint32_t role;         // 0 other, 1 master, 2 slave
 };
 
-struct ofp_nicira_controller_role_reply {
+struct of_nicira_controller_role_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
-    uint32_t experimenter; // OF_EXPERIMENTER_ID_NICIRA 0x00002320
-    uint32_t subtype;      // 11
+    uint32_t experimenter == 0x2320;
+    uint32_t subtype == 11;
     uint32_t role;         // 0 other, 1 master, 2 slave
 };
diff --git a/openflow_input/oxm-1.2 b/openflow_input/oxm-1.2
new file mode 100644
index 0000000..b18c6fb
--- /dev/null
+++ b/openflow_input/oxm-1.2
@@ -0,0 +1,435 @@
+// Copyright 2013, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL 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
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+//
+// Also derived from the OpenFlow header files which have these copyrights:
+// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+// Copyright (c) 2011, 2012 Open Networking Foundation
+
+#version 3
+#version 4
+
+/* TODO fix the C backend to not require this */
+struct of_oxm {
+    uint32_t type_len;
+};
+
+
+struct of_oxm_arp_op {
+    uint32_t type_len == 0x80002a02;
+    uint16_t value;
+};
+
+struct of_oxm_arp_op_masked {
+    uint32_t type_len == 0x80002b04;
+    uint16_t value;
+    uint16_t value_mask;
+};
+
+struct of_oxm_arp_sha {
+    uint32_t type_len == 0x80003006;
+    of_mac_addr_t value;
+};
+
+struct of_oxm_arp_sha_masked {
+    uint32_t type_len == 0x8000310c;
+    of_mac_addr_t value;
+    of_mac_addr_t value_mask;
+};
+
+struct of_oxm_arp_spa {
+    uint32_t type_len == 0x80002c04;
+    uint32_t value;
+};
+
+struct of_oxm_arp_spa_masked {
+    uint32_t type_len == 0x80002d08;
+    uint32_t value;
+    uint32_t value_mask;
+};
+
+struct of_oxm_arp_tha {
+    uint32_t type_len == 0x80003206;
+    of_mac_addr_t value;
+};
+
+struct of_oxm_arp_tha_masked {
+    uint32_t type_len == 0x8000330c;
+    of_mac_addr_t value;
+    of_mac_addr_t value_mask;
+};
+
+struct of_oxm_arp_tpa {
+    uint32_t type_len == 0x80002e04;
+    uint32_t value;
+};
+
+struct of_oxm_arp_tpa_masked {
+    uint32_t type_len == 0x80002f08;
+    uint32_t value;
+    uint32_t value_mask;
+};
+
+struct of_oxm_eth_dst {
+    uint32_t type_len == 0x80000606;
+    of_mac_addr_t value;
+};
+
+struct of_oxm_eth_dst_masked {
+    uint32_t type_len == 0x8000070c;
+    of_mac_addr_t value;
+    of_mac_addr_t value_mask;
+};
+
+struct of_oxm_eth_src {
+    uint32_t type_len == 0x80000806;
+    of_mac_addr_t value;
+};
+
+struct of_oxm_eth_src_masked {
+    uint32_t type_len == 0x8000090c;
+    of_mac_addr_t value;
+    of_mac_addr_t value_mask;
+};
+
+struct of_oxm_eth_type {
+    uint32_t type_len == 0x80000a02;
+    uint16_t value;
+};
+
+struct of_oxm_eth_type_masked {
+    uint32_t type_len == 0x80000b04;
+    uint16_t value;
+    uint16_t value_mask;
+};
+
+struct of_oxm_icmpv4_code {
+    uint32_t type_len == 0x80002801;
+    uint8_t value;
+};
+
+struct of_oxm_icmpv4_code_masked {
+    uint32_t type_len == 0x80002902;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_icmpv4_type {
+    uint32_t type_len == 0x80002601;
+    uint8_t value;
+};
+
+struct of_oxm_icmpv4_type_masked {
+    uint32_t type_len == 0x80002702;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_icmpv6_code {
+    uint32_t type_len == 0x80003c01;
+    uint8_t value;
+};
+
+struct of_oxm_icmpv6_code_masked {
+    uint32_t type_len == 0x80003d02;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_icmpv6_type {
+    uint32_t type_len == 0x80003a01;
+    uint8_t value;
+};
+
+struct of_oxm_icmpv6_type_masked {
+    uint32_t type_len == 0x80003b02;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_in_phy_port {
+    uint32_t type_len == 0x80000204;
+    of_port_no_t value;
+};
+
+struct of_oxm_in_phy_port_masked {
+    uint32_t type_len == 0x80000308;
+    of_port_no_t value;
+    of_port_no_t value_mask;
+};
+
+struct of_oxm_in_port {
+    uint32_t type_len == 0x80000004;
+    of_port_no_t value;
+};
+
+struct of_oxm_in_port_masked {
+    uint32_t type_len == 0x80000108;
+    of_port_no_t value;
+    of_port_no_t value_mask;
+};
+
+struct of_oxm_ip_dscp {
+    uint32_t type_len == 0x80001001;
+    uint8_t value;
+};
+
+struct of_oxm_ip_dscp_masked {
+    uint32_t type_len == 0x80001102;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_ip_ecn {
+    uint32_t type_len == 0x80001201;
+    uint8_t value;
+};
+
+struct of_oxm_ip_ecn_masked {
+    uint32_t type_len == 0x80001302;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_ip_proto {
+    uint32_t type_len == 0x80001401;
+    uint8_t value;
+};
+
+struct of_oxm_ip_proto_masked {
+    uint32_t type_len == 0x80001502;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_ipv4_dst {
+    uint32_t type_len == 0x80001804;
+    uint32_t value;
+};
+
+struct of_oxm_ipv4_dst_masked {
+    uint32_t type_len == 0x80001908;
+    uint32_t value;
+    uint32_t value_mask;
+};
+
+struct of_oxm_ipv4_src {
+    uint32_t type_len == 0x80001604;
+    uint32_t value;
+};
+
+struct of_oxm_ipv4_src_masked {
+    uint32_t type_len == 0x80001708;
+    uint32_t value;
+    uint32_t value_mask;
+};
+
+struct of_oxm_ipv6_dst {
+    uint32_t type_len == 0x80003610;
+    of_ipv6_t value;
+};
+
+struct of_oxm_ipv6_dst_masked {
+    uint32_t type_len == 0x80003720;
+    of_ipv6_t value;
+    of_ipv6_t value_mask;
+};
+
+struct of_oxm_ipv6_flabel {
+    uint32_t type_len == 0x80003804;
+    uint32_t value;
+};
+
+struct of_oxm_ipv6_flabel_masked {
+    uint32_t type_len == 0x80003908;
+    uint32_t value;
+    uint32_t value_mask;
+};
+
+struct of_oxm_ipv6_nd_sll {
+    uint32_t type_len == 0x80004006;
+    of_mac_addr_t value;
+};
+
+struct of_oxm_ipv6_nd_sll_masked {
+    uint32_t type_len == 0x8000410c;
+    of_mac_addr_t value;
+    of_mac_addr_t value_mask;
+};
+
+struct of_oxm_ipv6_nd_target {
+    uint32_t type_len == 0x80003e10;
+    of_ipv6_t value;
+};
+
+struct of_oxm_ipv6_nd_target_masked {
+    uint32_t type_len == 0x80003f20;
+    of_ipv6_t value;
+    of_ipv6_t value_mask;
+};
+
+struct of_oxm_ipv6_nd_tll {
+    uint32_t type_len == 0x80004206;
+    of_mac_addr_t value;
+};
+
+struct of_oxm_ipv6_nd_tll_masked {
+    uint32_t type_len == 0x8000430c;
+    of_mac_addr_t value;
+    of_mac_addr_t value_mask;
+};
+
+struct of_oxm_ipv6_src {
+    uint32_t type_len == 0x80003410;
+    of_ipv6_t value;
+};
+
+struct of_oxm_ipv6_src_masked {
+    uint32_t type_len == 0x80003520;
+    of_ipv6_t value;
+    of_ipv6_t value_mask;
+};
+
+struct of_oxm_metadata {
+    uint32_t type_len == 0x80000408;
+    uint64_t value;
+};
+
+struct of_oxm_metadata_masked {
+    uint32_t type_len == 0x80000510;
+    uint64_t value;
+    uint64_t value_mask;
+};
+
+struct of_oxm_mpls_label {
+    uint32_t type_len == 0x80004404;
+    uint32_t value;
+};
+
+struct of_oxm_mpls_label_masked {
+    uint32_t type_len == 0x80004508;
+    uint32_t value;
+    uint32_t value_mask;
+};
+
+struct of_oxm_mpls_tc {
+    uint32_t type_len == 0x80004601;
+    uint8_t value;
+};
+
+struct of_oxm_mpls_tc_masked {
+    uint32_t type_len == 0x80004702;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_sctp_dst {
+    uint32_t type_len == 0x80002402;
+    uint16_t value;
+};
+
+struct of_oxm_sctp_dst_masked {
+    uint32_t type_len == 0x80002504;
+    uint16_t value;
+    uint16_t value_mask;
+};
+
+struct of_oxm_sctp_src {
+    uint32_t type_len == 0x80002202;
+    uint16_t value;
+};
+
+struct of_oxm_sctp_src_masked {
+    uint32_t type_len == 0x80002304;
+    uint16_t value;
+    uint16_t value_mask;
+};
+
+struct of_oxm_tcp_dst {
+    uint32_t type_len == 0x80001c02;
+    uint16_t value;
+};
+
+struct of_oxm_tcp_dst_masked {
+    uint32_t type_len == 0x80001d04;
+    uint16_t value;
+    uint16_t value_mask;
+};
+
+struct of_oxm_tcp_src {
+    uint32_t type_len == 0x80001a02;
+    uint16_t value;
+};
+
+struct of_oxm_tcp_src_masked {
+    uint32_t type_len == 0x80001b04;
+    uint16_t value;
+    uint16_t value_mask;
+};
+
+struct of_oxm_udp_dst {
+    uint32_t type_len == 0x80002002;
+    uint16_t value;
+};
+
+struct of_oxm_udp_dst_masked {
+    uint32_t type_len == 0x80002104;
+    uint16_t value;
+    uint16_t value_mask;
+};
+
+struct of_oxm_udp_src {
+    uint32_t type_len == 0x80001e02;
+    uint16_t value;
+};
+
+struct of_oxm_udp_src_masked {
+    uint32_t type_len == 0x80001f04;
+    uint16_t value;
+    uint16_t value_mask;
+};
+
+struct of_oxm_vlan_pcp {
+    uint32_t type_len == 0x80000e01;
+    uint8_t value;
+};
+
+struct of_oxm_vlan_pcp_masked {
+    uint32_t type_len == 0x80000f02;
+    uint8_t value;
+    uint8_t value_mask;
+};
+
+struct of_oxm_vlan_vid {
+    uint32_t type_len == 0x80000c02;
+    uint16_t value;
+};
+
+struct of_oxm_vlan_vid_masked {
+    uint32_t type_len == 0x80000d04;
+    uint16_t value;
+    uint16_t value_mask;
+};
diff --git a/openflow_input/standard-1.0 b/openflow_input/standard-1.0
index c191b89..5d4405c 100644
--- a/openflow_input/standard-1.0
+++ b/openflow_input/standard-1.0
@@ -296,39 +296,39 @@
     OFPQOFC_EPERM = 2,
 };
 
-struct ofp_header {
+struct of_header {
     uint8_t version;
     uint8_t type;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_hello {
+struct of_hello {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 0;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_echo_request {
+struct of_echo_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 2;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
 };
 
-struct ofp_echo_reply {
+struct of_echo_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 3;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
 };
 
-struct ofp_experimenter {
+struct of_experimenter {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
     uint32_t experimenter;
@@ -336,46 +336,46 @@
     of_octets_t data;
 };
 
-struct ofp_barrier_request {
+struct of_barrier_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_barrier_reply {
+struct of_barrier_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_get_config_request {
+struct of_get_config_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 7;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_get_config_reply {
+struct of_get_config_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 8;
     uint16_t length;
     uint32_t xid;
     uint16_t flags;
     uint16_t miss_send_len;
 };
 
-struct ofp_set_config {
+struct of_set_config {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 9;
     uint16_t length;
     uint32_t xid;
     uint16_t flags;
     uint16_t miss_send_len;
 };
 
-struct ofp_port_desc {
+struct of_port_desc {
     of_port_no_t port_no;
     of_mac_addr_t hw_addr;
     of_port_name_t name;
@@ -387,40 +387,40 @@
     uint32_t peer;
 };
 
-struct ofp_features_request {
+struct of_features_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 5;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_features_reply {
+struct of_features_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 6;
     uint16_t length;
     uint32_t xid;
     uint64_t datapath_id;
     uint32_t n_buffers;
     uint8_t n_tables;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t capabilities;
     uint32_t actions;
     list(of_port_desc_t) ports;
 };
 
-struct ofp_port_status {
+struct of_port_status {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 12;
     uint16_t length;
     uint32_t xid;
     uint8_t reason;
-    uint8_t[7] pad;
+    pad(7);
     of_port_desc_t desc;
 };
 
-struct ofp_port_mod {
+struct of_port_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 15;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port_no;
@@ -428,120 +428,120 @@
     uint32_t config;
     uint32_t mask;
     uint32_t advertise;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_packet_in {
+struct of_packet_in {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 10;
     uint16_t length;
     uint32_t xid;
     uint32_t buffer_id;
     uint16_t total_len;
     of_port_no_t in_port;
     uint8_t reason;
-    uint8_t pad;
+    pad(1);
     of_octets_t data;
 };
 
-struct ofp_action_output {
-    uint16_t type;
+struct of_action_output {
+    uint16_t type == 0;
     uint16_t len;
     of_port_no_t port;
     uint16_t max_len;
 };
 
-struct ofp_action_set_vlan_vid {
-    uint16_t type;
+struct of_action_set_vlan_vid {
+    uint16_t type == 1;
     uint16_t len;
     uint16_t vlan_vid;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_strip_vlan {
-    uint16_t type;
+struct of_action_strip_vlan {
+    uint16_t type == 3;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_set_vlan_pcp {
-    uint16_t type;
+struct of_action_set_vlan_pcp {
+    uint16_t type == 2;
     uint16_t len;
     uint8_t vlan_pcp;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_set_dl_src {
-    uint16_t type;
+struct of_action_set_dl_src {
+    uint16_t type == 4;
     uint16_t len;
     of_mac_addr_t dl_addr;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_action_set_dl_dst {
-    uint16_t type;
+struct of_action_set_dl_dst {
+    uint16_t type == 5;
     uint16_t len;
     of_mac_addr_t dl_addr;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_action_set_nw_src {
-    uint16_t type;
+struct of_action_set_nw_src {
+    uint16_t type == 6;
     uint16_t len;
     uint32_t nw_addr;
 };
 
-struct ofp_action_set_nw_dst {
-    uint16_t type;
+struct of_action_set_nw_dst {
+    uint16_t type == 7;
     uint16_t len;
     uint32_t nw_addr;
 };
 
-struct ofp_action_set_tp_src {
-    uint16_t type;
+struct of_action_set_tp_src {
+    uint16_t type == 9;
     uint16_t len;
     uint16_t tp_port;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_set_tp_dst {
-    uint16_t type;
+struct of_action_set_tp_dst {
+    uint16_t type == 10;
     uint16_t len;
     uint16_t tp_port;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_set_nw_tos {
-    uint16_t type;
+struct of_action_set_nw_tos {
+    uint16_t type == 8;
     uint16_t len;
     uint8_t nw_tos;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_experimenter {
-    uint16_t type;
+struct of_action_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
     uint32_t experimenter;
     of_octets_t data;
 };
 
-struct ofp_action_enqueue {
-    uint16_t type;
+struct of_action_enqueue {
+    uint16_t type == 11;
     uint16_t len;
     of_port_no_t port;
-    uint8_t[6] pad;
+    pad(6);
     uint32_t queue_id;
 };
 
-struct ofp_action {
+struct of_action {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_packet_out {
+struct of_packet_out {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 13;
     uint16_t length;
     uint32_t xid;
     uint32_t buffer_id;
@@ -551,32 +551,32 @@
     of_octets_t data;
 };
 
-struct ofp_match_v1 {
+struct of_match_v1 {
     of_wc_bmap_t wildcards;
     of_port_no_t in_port;
     of_mac_addr_t eth_src;
     of_mac_addr_t eth_dst;
     uint16_t vlan_vid;
     uint8_t vlan_pcp;
-    uint8_t[1] pad1;
+    pad(1);
     uint16_t eth_type;
     uint8_t ip_dscp;
     uint8_t ip_proto;
-    uint8_t[2] pad2;
+    pad(2);
     uint32_t ipv4_src;
     uint32_t ipv4_dst;
     uint16_t tcp_src;
     uint16_t tcp_dst;
 };
 
-struct ofp_flow_add {
+struct of_flow_add {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     of_match_t match;
     uint64_t cookie;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 0;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -586,14 +586,14 @@
     list(of_action_t) actions;
 };
 
-struct ofp_flow_modify {
+struct of_flow_modify {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     of_match_t match;
     uint64_t cookie;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 1;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -603,14 +603,14 @@
     list(of_action_t) actions;
 };
 
-struct ofp_flow_modify_strict {
+struct of_flow_modify_strict {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     of_match_t match;
     uint64_t cookie;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 2;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -620,14 +620,14 @@
     list(of_action_t) actions;
 };
 
-struct ofp_flow_delete {
+struct of_flow_delete {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     of_match_t match;
     uint64_t cookie;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 3;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -637,14 +637,14 @@
     list(of_action_t) actions;
 };
 
-struct ofp_flow_delete_strict {
+struct of_flow_delete_strict {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     of_match_t match;
     uint64_t cookie;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 4;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -654,27 +654,27 @@
     list(of_action_t) actions;
 };
 
-struct ofp_flow_removed {
+struct of_flow_removed {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 11;
     uint16_t length;
     uint32_t xid;
     of_match_t match;
     uint64_t cookie;
     uint16_t priority;
     uint8_t reason;
-    uint8_t[1] pad;
+    pad(1);
     uint32_t duration_sec;
     uint32_t duration_nsec;
     uint16_t idle_timeout;
-    uint8_t[2] pad2;
+    pad(2);
     uint64_t packet_count;
     uint64_t byte_count;
 };
 
-struct ofp_error_msg {
+struct of_error_msg {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 1;
     uint16_t length;
     uint32_t xid;
     uint16_t err_type;
@@ -683,26 +683,26 @@
 };
 
 // STATS ENTRIES: flow, table, port, queue,
-struct ofp_flow_stats_entry {
+struct of_flow_stats_entry {
     uint16_t length;
     uint8_t table_id;
-    uint8_t pad;
+    pad(1);
     of_match_t match;
     uint32_t duration_sec;
     uint32_t duration_nsec;
     uint16_t priority;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
-    uint8_t[6] pad2;
+    pad(6);
     uint64_t cookie;
     uint64_t packet_count;
     uint64_t byte_count;
     list(of_action_t) actions;
 };
 
-struct ofp_table_stats_entry {
+struct of_table_stats_entry {
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     of_table_name_t name;
     of_wc_bmap_t wildcards;
     uint32_t max_entries;
@@ -711,9 +711,9 @@
     uint64_t matched_count;
 };
 
-struct ofp_port_stats_entry {
+struct of_port_stats_entry {
     of_port_no_t port_no;
-    uint8_t[6] pad;
+    pad(6);
     uint64_t rx_packets;
     uint64_t tx_packets;
     uint64_t rx_bytes;
@@ -728,9 +728,9 @@
     uint64_t collisions;
 };
 
-struct ofp_queue_stats_entry {
+struct of_queue_stats_entry {
     of_port_no_t port_no;
-    uint8_t[2] pad;
+    pad(2);
     uint32_t queue_id;
     uint64_t tx_bytes;
     uint64_t tx_packets;
@@ -739,21 +739,21 @@
 
 // STATS request/reply:  Desc, flow, agg, table, port, queue
 
-struct ofp_desc_stats_request {
+struct of_desc_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0;
     uint16_t flags;
 };
 
-struct ofp_desc_stats_reply {
+struct of_desc_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0;
     uint16_t flags;
     of_desc_str_t mfr_desc;
     of_desc_str_t hw_desc;
@@ -762,134 +762,134 @@
     of_desc_str_t dp_desc;
 };
 
-struct ofp_flow_stats_request {
+struct of_flow_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 1;
     uint16_t flags;
     of_match_t match;
     uint8_t table_id;
-    uint8_t pad;
+    pad(1);
     of_port_no_t out_port;
 };
 
-struct ofp_flow_stats_reply {
+struct of_flow_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 1;
     uint16_t flags;
     list(of_flow_stats_entry_t) entries;
 };
 
-struct ofp_aggregate_stats_request {
+struct of_aggregate_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 2;
     uint16_t flags;
     of_match_t match;
     uint8_t table_id;
-    uint8_t pad;
+    pad(1);
     of_port_no_t out_port;
 };
 
-struct ofp_aggregate_stats_reply {
+struct of_aggregate_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 2;
     uint16_t flags;
     uint64_t packet_count;
     uint64_t byte_count;
     uint32_t flow_count;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_table_stats_request {
+struct of_table_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 3;
     uint16_t flags;
 };
 
-struct ofp_table_stats_reply {
+struct of_table_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 3;
     uint16_t flags;
     list(of_table_stats_entry_t) entries;
 };
 
-struct ofp_port_stats_request {
+struct of_port_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 4;
     uint16_t flags;
     of_port_no_t port_no;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_port_stats_reply {
+struct of_port_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 4;
     uint16_t flags;
     list(of_port_stats_entry_t) entries;
 };
 
-struct ofp_queue_stats_request {
+struct of_queue_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 5;
     uint16_t flags;
     of_port_no_t port_no;
-    uint8_t[2] pad;
+    pad(2);
     uint32_t queue_id;
 };
 
-struct ofp_queue_stats_reply {
+struct of_queue_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 5;
     uint16_t flags;
     list(of_queue_stats_entry_t) entries;
 };
 
-struct ofp_experimenter_stats_request {
+struct of_experimenter_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0xffff;
     uint16_t flags;
     uint32_t experimenter;
     of_octets_t data;
 };
 
-struct ofp_experimenter_stats_reply {
+struct of_experimenter_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0xffff;
     uint16_t flags;
     uint32_t experimenter;
     of_octets_t data;
@@ -897,42 +897,42 @@
 
 // END OF STATS OBJECTS
 
-struct ofp_queue_prop {
+struct of_queue_prop {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_queue_prop_min_rate {
-    uint16_t type;
+struct of_queue_prop_min_rate {
+    uint16_t type == 1;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint16_t rate;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_packet_queue {
+struct of_packet_queue {
     uint32_t queue_id;
     uint16_t len;
-    uint8_t[2] pad;
+    pad(2);
     list(of_queue_prop_t) properties;
 };
 
-struct ofp_queue_get_config_request {
+struct of_queue_get_config_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 20;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_queue_get_config_reply {
+struct of_queue_get_config_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 21;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port;
-    uint8_t[6] pad;
+    pad(6);
     list(of_packet_queue_t) queues;
 };
diff --git a/openflow_input/standard-1.1 b/openflow_input/standard-1.1
index 1c551d2..a477d55 100644
--- a/openflow_input/standard-1.1
+++ b/openflow_input/standard-1.1
@@ -407,39 +407,39 @@
     OFPQT_MIN_RATE = 1,
 };
 
-struct ofp_header {
+struct of_header {
     uint8_t version;
     uint8_t type;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_hello {
+struct of_hello {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 0;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_echo_request {
+struct of_echo_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 2;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
 };
 
-struct ofp_echo_reply {
+struct of_echo_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 3;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
 };
 
-struct ofp_experimenter {
+struct of_experimenter {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
     uint32_t experimenter;
@@ -447,60 +447,60 @@
     of_octets_t data;
 };
 
-struct ofp_barrier_request {
+struct of_barrier_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 20;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_barrier_reply {
+struct of_barrier_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 21;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_get_config_request {
+struct of_get_config_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 7;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_get_config_reply {
+struct of_get_config_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 8;
     uint16_t length;
     uint32_t xid;
     uint16_t flags;
     uint16_t miss_send_len;
 };
 
-struct ofp_set_config {
+struct of_set_config {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 9;
     uint16_t length;
     uint32_t xid;
     uint16_t flags;
     uint16_t miss_send_len;
 };
 
-struct ofp_table_mod {
+struct of_table_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t config;
 };
 
-struct ofp_port_desc {
+struct of_port_desc {
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     of_mac_addr_t hw_addr;
-    uint8_t[2] pad2;
+    pad(2);
     of_port_name_t name;
     uint32_t config;
     uint32_t state;
@@ -512,55 +512,55 @@
     uint32_t max_speed;
 };
 
-struct ofp_features_request {
+struct of_features_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 5;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_features_reply {
+struct of_features_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 6;
     uint16_t length;
     uint32_t xid;
     uint64_t datapath_id;
     uint32_t n_buffers;
     uint8_t n_tables;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t capabilities;
     uint32_t reserved;
     list(of_port_desc_t) ports;
 };
 
-struct ofp_port_status {
+struct of_port_status {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 12;
     uint16_t length;
     uint32_t xid;
     uint8_t reason;
-    uint8_t[7] pad;
+    pad(7);
     of_port_desc_t desc;
 };
 
-struct ofp_port_mod {
+struct of_port_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     of_mac_addr_t hw_addr;
-    uint8_t[2] pad2;
+    pad(2);
     uint32_t config;
     uint32_t mask;
     uint32_t advertise;
-    uint8_t[4] pad3;
+    pad(4);
 };
 
-struct ofp_packet_in {
+struct of_packet_in {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 10;
     uint16_t length;
     uint32_t xid;
     uint32_t buffer_id;
@@ -572,200 +572,200 @@
     of_octets_t data;
 };
 
-struct ofp_action_output {
-    uint16_t type;
+struct of_action_output {
+    uint16_t type == 0;
     uint16_t len;
     of_port_no_t port;
     uint16_t max_len;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_action_set_vlan_vid {
-    uint16_t type;
+struct of_action_set_vlan_vid {
+    uint16_t type == 1;
     uint16_t len;
     uint16_t vlan_vid;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_set_vlan_pcp {
-    uint16_t type;
+struct of_action_set_vlan_pcp {
+    uint16_t type == 2;
     uint16_t len;
     uint8_t vlan_pcp;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_set_dl_src {
-    uint16_t type;
+struct of_action_set_dl_src {
+    uint16_t type == 3;
     uint16_t len;
     of_mac_addr_t dl_addr;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_action_set_dl_dst {
-    uint16_t type;
+struct of_action_set_dl_dst {
+    uint16_t type == 4;
     uint16_t len;
     of_mac_addr_t dl_addr;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_action_set_nw_src {
-    uint16_t type;
+struct of_action_set_nw_src {
+    uint16_t type == 5;
     uint16_t len;
     uint32_t nw_addr;
 };
 
-struct ofp_action_set_nw_dst {
-    uint16_t type;
+struct of_action_set_nw_dst {
+    uint16_t type == 6;
     uint16_t len;
     uint32_t nw_addr;
 };
 
-struct ofp_action_set_nw_tos {
-    uint16_t type;
+struct of_action_set_nw_tos {
+    uint16_t type == 7;
     uint16_t len;
     uint8_t nw_tos;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_set_nw_ecn {
-    uint16_t type;
+struct of_action_set_nw_ecn {
+    uint16_t type == 8;
     uint16_t len;
     uint8_t nw_ecn;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_set_tp_src {
-    uint16_t type;
+struct of_action_set_tp_src {
+    uint16_t type == 9;
     uint16_t len;
     uint16_t tp_port;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_set_tp_dst {
-    uint16_t type;
+struct of_action_set_tp_dst {
+    uint16_t type == 10;
     uint16_t len;
     uint16_t tp_port;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_copy_ttl_out {
-    uint16_t type;
+struct of_action_copy_ttl_out {
+    uint16_t type == 11;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_copy_ttl_in {
-    uint16_t type;
+struct of_action_copy_ttl_in {
+    uint16_t type == 12;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_set_mpls_label {
-    uint16_t type;
+struct of_action_set_mpls_label {
+    uint16_t type == 13;
     uint16_t len;
     uint32_t mpls_label;
 };
 
-struct ofp_action_set_mpls_tc {
-    uint16_t type;
+struct of_action_set_mpls_tc {
+    uint16_t type == 14;
     uint16_t len;
     uint8_t mpls_tc;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_set_mpls_ttl {
-    uint16_t type;
+struct of_action_set_mpls_ttl {
+    uint16_t type == 15;
     uint16_t len;
     uint8_t mpls_ttl;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_dec_mpls_ttl {
-    uint16_t type;
+struct of_action_dec_mpls_ttl {
+    uint16_t type == 16;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_push_vlan {
-    uint16_t type;
+struct of_action_push_vlan {
+    uint16_t type == 17;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_pop_vlan {
-    uint16_t type;
+struct of_action_pop_vlan {
+    uint16_t type == 18;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_push_mpls {
-    uint16_t type;
+struct of_action_push_mpls {
+    uint16_t type == 19;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_pop_mpls {
-    uint16_t type;
+struct of_action_pop_mpls {
+    uint16_t type == 20;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_set_queue {
-    uint16_t type;
+struct of_action_set_queue {
+    uint16_t type == 21;
     uint16_t len;
     uint32_t queue_id;
 };
 
-struct ofp_action_group {
-    uint16_t type;
+struct of_action_group {
+    uint16_t type == 22;
     uint16_t len;
     uint32_t group_id;
 };
 
-struct ofp_action_set_nw_ttl {
-    uint16_t type;
+struct of_action_set_nw_ttl {
+    uint16_t type == 23;
     uint16_t len;
     uint8_t nw_ttl;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_dec_nw_ttl {
-    uint16_t type;
+struct of_action_dec_nw_ttl {
+    uint16_t type == 24;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_experimenter {
-    uint16_t type;
+struct of_action_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
     uint32_t experimenter;
     of_octets_t data;
 };
 
-struct ofp_action {
+struct of_action {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_packet_out {
+struct of_packet_out {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 13;
     uint16_t length;
     uint32_t xid;
     uint32_t buffer_id;
     of_port_no_t in_port;
     uint16_t actions_len;
-    uint8_t[6] pad;
+    pad(6);
     list(of_action_t) actions;
     of_octets_t data;
 };
 
-struct ofp_match_v2 {
-    uint16_t type;
+struct of_match_v2 {
+    uint16_t type == 0;
     uint16_t length;
     of_port_no_t in_port;
     of_wc_bmap_t wildcards;
@@ -775,7 +775,7 @@
     of_mac_addr_t eth_dst_mask;
     uint16_t vlan_vid;
     uint8_t vlan_pcp;
-    uint8_t[1] pad1;
+    pad(1);
     uint16_t eth_type;
     uint8_t ip_dscp;
     uint8_t ip_proto;
@@ -787,68 +787,68 @@
     uint16_t tcp_dst;
     uint32_t mpls_label;
     uint8_t mpls_tc;
-    uint8_t[3] pad2;
+    pad(3);
     uint64_t metadata;
     uint64_t metadata_mask;
 };
 
-struct ofp_instruction {
+struct of_instruction {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_instruction_goto_table {
-    uint16_t type;
+struct of_instruction_goto_table {
+    uint16_t type == 1;
     uint16_t len;
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_instruction_write_metadata {
-    uint16_t type;
+struct of_instruction_write_metadata {
+    uint16_t type == 2;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t metadata;
     uint64_t metadata_mask;
 };
 
-struct ofp_instruction_write_actions {
-    uint16_t type;
+struct of_instruction_write_actions {
+    uint16_t type == 3;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_instruction_apply_actions {
-    uint16_t type;
+struct of_instruction_apply_actions {
+    uint16_t type == 4;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_instruction_clear_actions {
-    uint16_t type;
+struct of_instruction_clear_actions {
+    uint16_t type == 5;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_instruction_experimenter {
-    uint16_t type;		
+struct of_instruction_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
     uint32_t experimenter;
     of_octets_t data;
 };
 
-struct ofp_flow_add {
+struct of_flow_add {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 0;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -856,20 +856,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_modify {
+struct of_flow_modify {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 1;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -877,20 +877,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_modify_strict {
+struct of_flow_modify_strict {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 2;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -898,20 +898,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_delete {
+struct of_flow_delete {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 3;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -919,20 +919,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_delete_strict {
+struct of_flow_delete_strict {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 4;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -940,35 +940,35 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_bucket {
+struct of_bucket {
     uint16_t len;
     uint16_t weight;
     of_port_no_t watch_port;
     uint32_t watch_group;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_group_mod {
+struct of_group_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 15;
     uint16_t length;
     uint32_t xid;
     uint16_t command;
     uint8_t group_type;
-    uint8_t pad;
+    pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
 };
 
-struct ofp_flow_removed {
+struct of_flow_removed {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 11;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
@@ -978,15 +978,15 @@
     uint32_t duration_sec;
     uint32_t duration_nsec;
     uint16_t idle_timeout;
-    uint8_t[2] pad2;
+    pad(2);
     uint64_t packet_count;
     uint64_t byte_count;
     of_match_t match;
 };
 
-struct ofp_error_msg {
+struct of_error_msg {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 1;
     uint16_t length;
     uint32_t xid;
     uint16_t err_type;
@@ -996,16 +996,16 @@
 
 // STATS ENTRIES:  flow, table, port, group, group_desc
 
-struct ofp_flow_stats_entry {
+struct of_flow_stats_entry {
     uint16_t length;
     uint8_t table_id;
-    uint8_t pad;
+    pad(1);
     uint32_t duration_sec;
     uint32_t duration_nsec;
     uint16_t priority;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
-    uint8_t[6] pad2;
+    pad(6);
     uint64_t cookie;
     uint64_t packet_count;
     uint64_t byte_count;
@@ -1013,9 +1013,9 @@
     list(of_instruction_t) instructions;
 };
 
-struct ofp_table_stats_entry {
+struct of_table_stats_entry {
     uint8_t table_id;
-    uint8_t[7] pad;
+    pad(7);
     of_table_name_t name;
     of_wc_bmap_t wildcards;
     of_match_bmap_t match;
@@ -1029,9 +1029,9 @@
     uint64_t matched_count;
 };
 
-struct ofp_port_stats_entry {
+struct of_port_stats_entry {
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t rx_packets;
     uint64_t tx_packets;
     uint64_t rx_bytes;
@@ -1046,7 +1046,7 @@
     uint64_t collisions;
 };
 
-struct ofp_queue_stats_entry {
+struct of_queue_stats_entry {
     of_port_no_t port_no;
     uint32_t queue_id;
     uint64_t tx_bytes;
@@ -1054,50 +1054,50 @@
     uint64_t tx_errors;
 };
 
-struct ofp_bucket_counter {
+struct of_bucket_counter {
     uint64_t packet_count;
     uint64_t byte_count;
 };
 
-struct ofp_group_stats_entry {
+struct of_group_stats_entry {
     uint16_t length;
-    uint8_t[2] pad;
+    pad(2);
     uint32_t group_id;
     uint32_t ref_count;
-    uint8_t[4] pad2;
+    pad(4);
     uint64_t packet_count;
     uint64_t byte_count;
     list(of_bucket_counter_t) bucket_stats;
 };
 
-struct ofp_group_desc_stats_entry {
+struct of_group_desc_stats_entry {
     uint16_t length;
     uint8_t type;
-    uint8_t pad;
+    pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
 };
 
 // STATS:  Desc, flow, agg, table, port, queue, group, group_desc, experi
 
-struct ofp_desc_stats_request {
+struct of_desc_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_desc_stats_reply {
+struct of_desc_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_desc_str_t mfr_desc;
     of_desc_str_t hw_desc;
     of_desc_str_t sw_desc;
@@ -1105,242 +1105,242 @@
     of_desc_str_t dp_desc;
 };
 
-struct ofp_flow_stats_request {
+struct of_flow_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 1;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     of_port_no_t out_port;
     uint32_t out_group;
-    uint8_t[4] pad2;
+    pad(4);
     uint64_t cookie;
     uint64_t cookie_mask;
     of_match_t match;
 };
 
-struct ofp_flow_stats_reply {
+struct of_flow_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 1;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_flow_stats_entry_t) entries;
 };
 
-struct ofp_aggregate_stats_request {
+struct of_aggregate_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 2;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     of_port_no_t out_port;
     uint32_t out_group;
-    uint8_t[4] pad2;
+    pad(4);
     uint64_t cookie;
     uint64_t cookie_mask;
     of_match_t match;
 };
 
-struct ofp_aggregate_stats_reply {
+struct of_aggregate_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 2;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t packet_count;
     uint64_t byte_count;
     uint32_t flow_count;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_table_stats_request {
+struct of_table_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 3;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_table_stats_reply {
+struct of_table_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 3;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_table_stats_entry_t) entries;
 };
 
-struct ofp_port_stats_request {
+struct of_port_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 4;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_port_stats_reply {
+struct of_port_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 4;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_port_stats_entry_t) entries;
 };
 
-struct ofp_queue_stats_request {
+struct of_queue_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 5;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_port_no_t port_no;
     uint32_t queue_id;
 };
 
-struct ofp_queue_stats_reply {
+struct of_queue_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 5;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_queue_stats_entry_t) entries;
 };
 
-struct ofp_group_stats_request {
+struct of_group_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 6;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t group_id;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_group_stats_reply {
+struct of_group_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 6;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_group_stats_entry_t) entries;
 };
 
-struct ofp_group_desc_stats_request {
+struct of_group_desc_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 7;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_group_desc_stats_reply {
+struct of_group_desc_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 7;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_group_desc_stats_entry_t) entries;
 };
 
-struct ofp_experimenter_stats_request {
+struct of_experimenter_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0xffff;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t experimenter;
-    uint8_t[4] pad;
+    pad(4);
     of_octets_t data;
 };
 
-struct ofp_experimenter_stats_reply {
+struct of_experimenter_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0xffff;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t experimenter;
-    uint8_t[4] pad;
+    pad(4);
     of_octets_t data;
 };
 
 // END OF STATS OBJECTS
 
-struct ofp_queue_prop {
+struct of_queue_prop {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_queue_prop_min_rate {
-    uint16_t type;
+struct of_queue_prop_min_rate {
+    uint16_t type == 1;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint16_t rate;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_packet_queue {
+struct of_packet_queue {
     uint32_t queue_id;
     uint16_t len;
-    uint8_t[2] pad;
+    pad(2);
     list(of_queue_prop_t) properties;
 };
 
-struct ofp_queue_get_config_request {
+struct of_queue_get_config_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 22;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_queue_get_config_reply {
+struct of_queue_get_config_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 23;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port;
-    uint8_t[4] pad;
+    pad(4);
     list(of_packet_queue_t) queues;
 };
diff --git a/openflow_input/standard-1.2 b/openflow_input/standard-1.2
index 0d48c43..4650e06 100644
--- a/openflow_input/standard-1.2
+++ b/openflow_input/standard-1.2
@@ -447,39 +447,39 @@
     OFPCR_ROLE_SLAVE = 3,
 };
 
-struct ofp_header {
+struct of_header {
     uint8_t version;
     uint8_t type;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_hello {
+struct of_hello {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 0;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_echo_request {
+struct of_echo_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 2;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
 };
 
-struct ofp_echo_reply {
+struct of_echo_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 3;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
 };
 
-struct ofp_experimenter {
+struct of_experimenter {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
     uint32_t experimenter;
@@ -487,60 +487,60 @@
     of_octets_t data;
 };
 
-struct ofp_barrier_request {
+struct of_barrier_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 20;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_barrier_reply {
+struct of_barrier_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 21;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_get_config_request {
+struct of_get_config_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 7;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_get_config_reply {
+struct of_get_config_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 8;
     uint16_t length;
     uint32_t xid;
     uint16_t flags;
     uint16_t miss_send_len;
 };
 
-struct ofp_set_config {
+struct of_set_config {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 9;
     uint16_t length;
     uint32_t xid;
     uint16_t flags;
     uint16_t miss_send_len;
 };
 
-struct ofp_table_mod {
+struct of_table_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t config;
 };
 
-struct ofp_port_desc {
+struct of_port_desc {
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     of_mac_addr_t hw_addr;
-    uint8_t[2] pad2;
+    pad(2);
     of_port_name_t name;
     uint32_t config;
     uint32_t state;
@@ -552,225 +552,219 @@
     uint32_t max_speed;
 };
 
-struct ofp_features_request {
+struct of_features_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 5;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_features_reply {
+struct of_features_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 6;
     uint16_t length;
     uint32_t xid;
     uint64_t datapath_id;
     uint32_t n_buffers;
     uint8_t n_tables;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t capabilities;
     uint32_t reserved;
     list(of_port_desc_t) ports;
 };
 
-struct ofp_port_status {
+struct of_port_status {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 12;
     uint16_t length;
     uint32_t xid;
     uint8_t reason;
-    uint8_t[7] pad;
+    pad(7);
     of_port_desc_t desc;
 };
 
-struct ofp_port_mod {
+struct of_port_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     of_mac_addr_t hw_addr;
-    uint8_t[2] pad2;
+    pad(2);
     uint32_t config;
     uint32_t mask;
     uint32_t advertise;
-    uint8_t[4] pad3;
+    pad(4);
 };
 
-struct ofp_match_v3 {
-    uint16_t type;
+struct of_match_v3 {
+    uint16_t type == 1;
     uint16_t length;
     list(of_oxm_t) oxm_list;
 };
 
-struct ofp_oxm_experimenter_header {
-    uint32_t oxm_header;
-    uint32_t experimenter;
-    of_octets_t data;
-};
-
-struct ofp_action_output {
-    uint16_t type;
+struct of_action_output {
+    uint16_t type == 0;
     uint16_t len;
     of_port_no_t port;
     uint16_t max_len;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_action_copy_ttl_out {
-    uint16_t type;
+struct of_action_copy_ttl_out {
+    uint16_t type == 11;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_copy_ttl_in {
-    uint16_t type;
+struct of_action_copy_ttl_in {
+    uint16_t type == 12;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_set_mpls_ttl {
-    uint16_t type;
+struct of_action_set_mpls_ttl {
+    uint16_t type == 15;
     uint16_t len;
     uint8_t mpls_ttl;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_dec_mpls_ttl {
-    uint16_t type;
+struct of_action_dec_mpls_ttl {
+    uint16_t type == 16;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_push_vlan {
-    uint16_t type;
+struct of_action_push_vlan {
+    uint16_t type == 17;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_pop_vlan {
-    uint16_t type;
+struct of_action_pop_vlan {
+    uint16_t type == 18;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_push_mpls {
-    uint16_t type;
+struct of_action_push_mpls {
+    uint16_t type == 19;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_pop_mpls {
-    uint16_t type;
+struct of_action_pop_mpls {
+    uint16_t type == 20;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_set_queue {
-    uint16_t type;
+struct of_action_set_queue {
+    uint16_t type == 21;
     uint16_t len;
     uint32_t queue_id;
 };
 
-struct ofp_action_group {
-    uint16_t type;
+struct of_action_group {
+    uint16_t type == 22;
     uint16_t len;
     uint32_t group_id;
 };
 
-struct ofp_action_set_nw_ttl {
-    uint16_t type;
+struct of_action_set_nw_ttl {
+    uint16_t type == 23;
     uint16_t len;
     uint8_t nw_ttl;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_dec_nw_ttl {
-    uint16_t type;
+struct of_action_dec_nw_ttl {
+    uint16_t type == 24;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_set_field {
-    uint16_t type;
+struct of_action_set_field {
+    uint16_t type == 25;
     uint16_t len;
     of_octets_t field;
 };
 
-struct ofp_action_experimenter {
-    uint16_t type;
+struct of_action_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
     uint32_t experimenter;
     of_octets_t data;
 };
 
-struct ofp_action {
+struct of_action {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_instruction {
+struct of_instruction {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_instruction_goto_table {
-    uint16_t type;
+struct of_instruction_goto_table {
+    uint16_t type == 1;
     uint16_t len;
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_instruction_write_metadata {
-    uint16_t type;
+struct of_instruction_write_metadata {
+    uint16_t type == 2;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t metadata;
     uint64_t metadata_mask;
 };
 
-struct ofp_instruction_write_actions {
-    uint16_t type;
+struct of_instruction_write_actions {
+    uint16_t type == 3;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_instruction_apply_actions {
-    uint16_t type;
+struct of_instruction_apply_actions {
+    uint16_t type == 4;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_instruction_clear_actions {
-    uint16_t type;
+struct of_instruction_clear_actions {
+    uint16_t type == 5;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_instruction_experimenter {
-    uint16_t type;		
+struct of_instruction_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
     uint32_t experimenter;
     of_octets_t data;
 };
 
-struct ofp_flow_add {
+struct of_flow_add {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 0;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -778,20 +772,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_modify {
+struct of_flow_modify {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 1;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -799,20 +793,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_modify_strict {
+struct of_flow_modify_strict {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 2;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -820,20 +814,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_delete {
+struct of_flow_delete {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 3;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -841,20 +835,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_delete_strict {
+struct of_flow_delete_strict {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 4;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -862,48 +856,48 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_bucket {
+struct of_bucket {
     uint16_t len;
     uint16_t weight;
     of_port_no_t watch_port;
     uint32_t watch_group;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_group_mod {
+struct of_group_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 15;
     uint16_t length;
     uint32_t xid;
     uint16_t command;
     uint8_t group_type;
-    uint8_t pad;
+    pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
 };
 
-struct ofp_packet_out {
+struct of_packet_out {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 13;
     uint16_t length;
     uint32_t xid;
     uint32_t buffer_id;
     of_port_no_t in_port;
     uint16_t actions_len;
-    uint8_t[6] pad;
+    pad(6);
     list(of_action_t) actions;
     of_octets_t data;
 };
 
-struct ofp_packet_in {
+struct of_packet_in {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 10;
     uint16_t length;
     uint32_t xid;
     uint32_t buffer_id;
@@ -911,13 +905,13 @@
     uint8_t reason;
     uint8_t table_id;
     of_match_t match;
-    uint8_t[2] pad;
+    pad(2);
     of_octets_t data; /* FIXME: Ensure total_len gets updated */
 };
 
-struct ofp_flow_removed {
+struct of_flow_removed {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 11;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
@@ -933,9 +927,9 @@
     of_match_t match;
 };
 
-struct ofp_error_msg {
+struct of_error_msg {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 1;
     uint16_t length;
     uint32_t xid;
     uint16_t err_type;
@@ -943,7 +937,7 @@
     of_octets_t data;
 };
 
-// struct ofp_error_experimenter_msg {
+// struct of_error_experimenter_msg {
 //    uint8_t version;
 //    uint8_t type;
 //    uint16_t length;
@@ -957,16 +951,16 @@
 // STATS ENTRIES: flow, table, port, queue, group stats, group desc stats
 // FIXME: Verify disambiguation w/ length in object and entry
 
-struct ofp_flow_stats_entry {
+struct of_flow_stats_entry {
     uint16_t length;
     uint8_t table_id;
-    uint8_t pad;
+    pad(1);
     uint32_t duration_sec;
     uint32_t duration_nsec;
     uint16_t priority;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
-    uint8_t[6] pad2;
+    pad(6);
     uint64_t cookie;
     uint64_t packet_count;
     uint64_t byte_count;
@@ -974,9 +968,9 @@
     list(of_instruction_t) instructions;
 };
 
-struct ofp_table_stats_entry {
+struct of_table_stats_entry {
     uint8_t table_id;
-    uint8_t[7] pad;
+    pad(7);
     of_table_name_t name;
     of_match_bmap_t match;
     of_wc_bmap_t wildcards;
@@ -994,9 +988,9 @@
     uint64_t matched_count;
 };
 
-struct ofp_port_stats_entry {
+struct of_port_stats_entry {
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t rx_packets;
     uint64_t tx_packets;
     uint64_t rx_bytes;
@@ -1011,7 +1005,7 @@
     uint64_t collisions;
 };
 
-struct ofp_queue_stats_entry {
+struct of_queue_stats_entry {
     of_port_no_t port_no;
     uint32_t queue_id;
     uint64_t tx_bytes;
@@ -1019,26 +1013,26 @@
     uint64_t tx_errors;
 };
 
-struct ofp_bucket_counter {
+struct of_bucket_counter {
     uint64_t packet_count;
     uint64_t byte_count;
 };
 
-struct ofp_group_stats_entry {
+struct of_group_stats_entry {
     uint16_t length;
-    uint8_t[2] pad;
+    pad(2);
     uint32_t group_id;
     uint32_t ref_count;
-    uint8_t[4] pad2;
+    pad(4);
     uint64_t packet_count;
     uint64_t byte_count;
     list(of_bucket_counter_t) bucket_stats;
 };
 
-struct ofp_group_desc_stats_entry {
+struct of_group_desc_stats_entry {
     uint16_t length;
     uint8_t type;
-    uint8_t pad;
+    pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
 };
@@ -1046,24 +1040,24 @@
 // STATS: 
 //  Desc, flow, agg, table, port, queue, group, group_desc, group_feat, experi
 
-struct ofp_desc_stats_request {
+struct of_desc_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_desc_stats_reply {
+struct of_desc_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_desc_str_t mfr_desc;
     of_desc_str_t hw_desc;
     of_desc_str_t sw_desc;
@@ -1071,196 +1065,196 @@
     of_desc_str_t dp_desc;
 };
 
-struct ofp_flow_stats_request {
+struct of_flow_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 1;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     of_port_no_t out_port;
     uint32_t out_group;
-    uint8_t[4] pad2;
+    pad(4);
     uint64_t cookie;
     uint64_t cookie_mask;
     of_match_t match;
 };
 
-struct ofp_flow_stats_reply {
+struct of_flow_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 1;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_flow_stats_entry_t) entries;
 };
 
-struct ofp_aggregate_stats_request {
+struct of_aggregate_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 2;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     of_port_no_t out_port;
     uint32_t out_group;
-    uint8_t[4] pad2;
+    pad(4);
     uint64_t cookie;
     uint64_t cookie_mask;
     of_match_t match;
 };
 
-struct ofp_aggregate_stats_reply {
+struct of_aggregate_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 2;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t packet_count;
     uint64_t byte_count;
     uint32_t flow_count;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_table_stats_request {
+struct of_table_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 3;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_table_stats_reply {
+struct of_table_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 3;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_table_stats_entry_t) entries;
 };
 
-struct ofp_port_stats_request {
+struct of_port_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 4;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_port_stats_reply {
+struct of_port_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 4;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_port_stats_entry_t) entries;
 };
 
-struct ofp_queue_stats_request {
+struct of_queue_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 5;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_port_no_t port_no;
     uint32_t queue_id;
 };
 
-struct ofp_queue_stats_reply {
+struct of_queue_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 5;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_queue_stats_entry_t) entries;
 };
 
-struct ofp_group_stats_request {
+struct of_group_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 6;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t group_id;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_group_stats_reply {
+struct of_group_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 6;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_group_stats_entry_t) entries;
 };
 
-struct ofp_group_desc_stats_request {
+struct of_group_desc_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 7;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_group_desc_stats_reply {
+struct of_group_desc_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 7;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_group_desc_stats_entry_t) entries;
 };
 
-struct ofp_group_features_stats_request {
+struct of_group_features_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 8;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_group_features_stats_reply {
+struct of_group_features_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 8;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t types;
     uint32_t capabilities;
     uint32_t max_groups_all;
@@ -1273,27 +1267,27 @@
     uint32_t actions_ff;
 };
 
-struct ofp_experimenter_stats_request {
+struct of_experimenter_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0xffff;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t experimenter;
     uint32_t subtype;
     of_octets_t data;
 };
 
-struct ofp_experimenter_stats_reply {
+struct of_experimenter_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0xffff;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t experimenter;
     uint32_t subtype;
     of_octets_t data;
@@ -1301,77 +1295,77 @@
 
 // END OF STATS OBJECTS
 
-struct ofp_queue_prop {
+struct of_queue_prop {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_queue_prop_min_rate {
-    uint16_t type;
+struct of_queue_prop_min_rate {
+    uint16_t type == 1;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint16_t rate;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_queue_prop_max_rate {
-    uint16_t type;
+struct of_queue_prop_max_rate {
+    uint16_t type == 2;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint16_t rate;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_queue_prop_experimenter {
-    uint16_t type;
+struct of_queue_prop_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t experimenter;
-    uint8_t[4] pad;
+    pad(4);
     of_octets_t data;
 };
 
-struct ofp_packet_queue {
+struct of_packet_queue {
     uint32_t queue_id;
     of_port_no_t port;
     uint16_t len;
-    uint8_t[6] pad;
+    pad(6);
     list(of_queue_prop_t) properties;
 };
 
-struct ofp_queue_get_config_request {
+struct of_queue_get_config_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 22;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_queue_get_config_reply {
+struct of_queue_get_config_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 23;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port;
-    uint8_t[4] pad;
+    pad(4);
     list(of_packet_queue_t) queues;
 };
 
-struct ofp_role_request {
+struct of_role_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 24;
     uint16_t length;
     uint32_t xid;
     uint32_t role;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t generation_id;
 };
 
-struct ofp_role_reply {
+struct of_role_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 25;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index e7a9812..ccef4db 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -548,7 +548,7 @@
     OFPHET_VERSIONBITMAP = 1,
 };
 
-struct ofp_header {
+struct of_header {
     uint8_t version;
     uint8_t type;
     uint16_t length;
@@ -556,53 +556,53 @@
 };
 
 // Special structures used for managing scalar list elements
-struct ofp_uint32 {
+struct of_uint32 {
     uint32_t value;
 };
 
 // Special structures used for managing scalar list elements
-struct ofp_uint8 {
+struct of_uint8 {
     uint8_t value;
 };
 
-struct ofp_hello_elem {
+struct of_hello_elem {
     uint16_t type;
     uint16_t length;
 };
 
-struct ofp_hello_elem_versionbitmap {
-    uint16_t type;
+struct of_hello_elem_versionbitmap {
+    uint16_t type == 1;
     uint16_t length;
     list(of_uint32_t) bitmaps;
 };
 
-struct ofp_hello {
+struct of_hello {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 0;
     uint16_t length;
     uint32_t xid;
     list(of_hello_elem_t) elements;
 };
 
-struct ofp_echo_request {
+struct of_echo_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 2;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
 };
 
-struct ofp_echo_reply {
+struct of_echo_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 3;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
 };
 
-struct ofp_experimenter {
+struct of_experimenter {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 4;
     uint16_t length;
     uint32_t xid;
     uint32_t experimenter;
@@ -610,60 +610,60 @@
     of_octets_t data;
 };
 
-struct ofp_barrier_request {
+struct of_barrier_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 20;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_barrier_reply {
+struct of_barrier_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 21;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_get_config_request {
+struct of_get_config_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 7;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_get_config_reply {
+struct of_get_config_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 8;
     uint16_t length;
     uint32_t xid;
     uint16_t flags;
     uint16_t miss_send_len;
 };
 
-struct ofp_set_config {
+struct of_set_config {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 9;
     uint16_t length;
     uint32_t xid;
     uint16_t flags;
     uint16_t miss_send_len;
 };
 
-struct ofp_table_mod {
+struct of_table_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 17;
     uint16_t length;
     uint32_t xid;
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t config;
 };
 
-struct ofp_port_desc {
+struct of_port_desc {
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     of_mac_addr_t hw_addr;
-    uint8_t[2] pad2;
+    pad(2);
     of_port_name_t name;
     uint32_t config;
     uint32_t state;
@@ -675,252 +675,246 @@
     uint32_t max_speed;
 };
 
-struct ofp_features_request {
+struct of_features_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 5;
     uint16_t length;
     uint32_t xid;
 };
 
-struct ofp_features_reply {
+struct of_features_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 6;
     uint16_t length;
     uint32_t xid;
     uint64_t datapath_id;
     uint32_t n_buffers;
     uint8_t n_tables;
     uint8_t auxiliary_id;
-    uint8_t[2] pad;
+    pad(2);
     uint32_t capabilities;
     uint32_t reserved;
 };
 
-struct ofp_port_status {
+struct of_port_status {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 12;
     uint16_t length;
     uint32_t xid;
     uint8_t reason;
-    uint8_t[7] pad;
+    pad(7);
     of_port_desc_t desc;
 };
 
-struct ofp_port_mod {
+struct of_port_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 16;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     of_mac_addr_t hw_addr;
-    uint8_t[2] pad2;
+    pad(2);
     uint32_t config;
     uint32_t mask;
     uint32_t advertise;
-    uint8_t[4] pad3;
+    pad(4);
 };
 
 // FIXME Does this need to be v4?
-struct ofp_match_v3 {
-    uint16_t type;
+struct of_match_v3 {
+    uint16_t type == 1;
     uint16_t length;
     list(of_oxm_t) oxm_list;
 };
 
-struct ofp_oxm_experimenter_header {
-    uint32_t oxm_header;
-    uint32_t experimenter;
-    of_octets_t data;
-};
-
 // This looks like an action header, but is standalone.  See 
 // ofp_table_features_prop_actions
-struct ofp_action_id {
+struct of_action_id {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_output {
-    uint16_t type;
+struct of_action_output {
+    uint16_t type == 0;
     uint16_t len;
     of_port_no_t port;
     uint16_t max_len;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_action_copy_ttl_out {
-    uint16_t type;
+struct of_action_copy_ttl_out {
+    uint16_t type == 11;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_copy_ttl_in {
-    uint16_t type;
+struct of_action_copy_ttl_in {
+    uint16_t type == 12;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_set_mpls_ttl {
-    uint16_t type;
+struct of_action_set_mpls_ttl {
+    uint16_t type == 15;
     uint16_t len;
     uint8_t mpls_ttl;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_dec_mpls_ttl {
-    uint16_t type;
+struct of_action_dec_mpls_ttl {
+    uint16_t type == 16;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_push_vlan {
-    uint16_t type;
+struct of_action_push_vlan {
+    uint16_t type == 17;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_pop_vlan {
-    uint16_t type;
+struct of_action_pop_vlan {
+    uint16_t type == 18;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_push_mpls {
-    uint16_t type;
+struct of_action_push_mpls {
+    uint16_t type == 19;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_pop_mpls {
-    uint16_t type;
+struct of_action_pop_mpls {
+    uint16_t type == 20;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action_set_queue {
-    uint16_t type;
+struct of_action_set_queue {
+    uint16_t type == 21;
     uint16_t len;
     uint32_t queue_id;
 };
 
-struct ofp_action_group {
-    uint16_t type;
+struct of_action_group {
+    uint16_t type == 22;
     uint16_t len;
     uint32_t group_id;
 };
 
-struct ofp_action_set_nw_ttl {
-    uint16_t type;
+struct of_action_set_nw_ttl {
+    uint16_t type == 23;
     uint16_t len;
     uint8_t nw_ttl;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_action_dec_nw_ttl {
-    uint16_t type;
+struct of_action_dec_nw_ttl {
+    uint16_t type == 24;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_set_field {
-    uint16_t type;
+struct of_action_set_field {
+    uint16_t type == 25;
     uint16_t len;
     of_octets_t field;
 };
 
-struct ofp_action_experimenter {
-    uint16_t type;
+struct of_action_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
     uint32_t experimenter;
     of_octets_t data;
 };
 
-struct ofp_action_pop_pbb {
-    uint16_t type;
+struct of_action_pop_pbb {
+    uint16_t type == 27;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_action_push_pbb {
-    uint16_t type;
+struct of_action_push_pbb {
+    uint16_t type == 26;
     uint16_t len;
     uint16_t ethertype;
-    uint8_t[2] pad;
+    pad(2);
 };
 
-struct ofp_action {
+struct of_action {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_instruction {
+struct of_instruction {
     uint16_t type;
     uint16_t len;
 };
 
-struct ofp_instruction_goto_table {
-    uint16_t type;
+struct of_instruction_goto_table {
+    uint16_t type == 1;
     uint16_t len;
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
 };
 
-struct ofp_instruction_write_metadata {
-    uint16_t type;
+struct of_instruction_write_metadata {
+    uint16_t type == 2;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t metadata;
     uint64_t metadata_mask;
 };
 
-struct ofp_instruction_write_actions {
-    uint16_t type;
+struct of_instruction_write_actions {
+    uint16_t type == 3;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_instruction_apply_actions {
-    uint16_t type;
+struct of_instruction_apply_actions {
+    uint16_t type == 4;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_instruction_clear_actions {
-    uint16_t type;
+struct of_instruction_clear_actions {
+    uint16_t type == 5;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_instruction_meter {
-    uint16_t type;
+struct of_instruction_meter {
+    uint16_t type == 6;
     uint16_t len;
     uint32_t meter_id;
 };
 
-struct ofp_instruction_experimenter {
-    uint16_t type;		
+struct of_instruction_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
     uint32_t experimenter;
     of_octets_t data;
 };
 
-struct ofp_flow_add {
+struct of_flow_add {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 0;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -928,20 +922,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_modify {
+struct of_flow_modify {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 1;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -949,20 +943,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_modify_strict {
+struct of_flow_modify_strict {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 2;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -970,20 +964,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_delete {
+struct of_flow_delete {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 3;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -991,20 +985,20 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_flow_delete_strict {
+struct of_flow_delete_strict {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 14;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
     uint64_t cookie_mask;
     uint8_t table_id;
-    of_fm_cmd_t _command;
+    of_fm_cmd_t _command == 4;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint16_t priority;
@@ -1012,48 +1006,48 @@
     of_port_no_t out_port;
     uint32_t out_group;
     uint16_t flags;
-    uint8_t[2] pad;
+    pad(2);
     of_match_t match;
     list(of_instruction_t) instructions;
 };
 
-struct ofp_bucket {
+struct of_bucket {
     uint16_t len;
     uint16_t weight;
     of_port_no_t watch_port;
     uint32_t watch_group;
-    uint8_t[4] pad;
+    pad(4);
     list(of_action_t) actions;
 };
 
-struct ofp_group_mod {
+struct of_group_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 15;
     uint16_t length;
     uint32_t xid;
     uint16_t command;
     uint8_t group_type;
-    uint8_t pad;
+    pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
 };
 
-struct ofp_packet_out {
+struct of_packet_out {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 13;
     uint16_t length;
     uint32_t xid;
     uint32_t buffer_id;
     of_port_no_t in_port;
     uint16_t actions_len;
-    uint8_t[6] pad;
+    pad(6);
     list(of_action_t) actions;
     of_octets_t data;
 };
 
-struct ofp_packet_in {
+struct of_packet_in {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 10;
     uint16_t length;
     uint32_t xid;
     uint32_t buffer_id;
@@ -1062,13 +1056,13 @@
     uint8_t table_id;
     uint64_t cookie;
     of_match_t match;
-    uint8_t[2] pad;
+    pad(2);
     of_octets_t data; /* FIXME: Ensure total_len gets updated */
 };
 
-struct ofp_flow_removed {
+struct of_flow_removed {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 11;
     uint16_t length;
     uint32_t xid;
     uint64_t cookie;
@@ -1084,41 +1078,41 @@
     of_match_t match;
 };
 
-struct ofp_meter_band {
+struct of_meter_band {
     uint16_t        type;
     uint16_t        len;
 //    uint32_t        rate;  // These are excluded b/c this is the header
 //    uint32_t        burst_size;  // These are excluded b/c this is the header
 };
 
-struct ofp_meter_band_drop {
-    uint16_t        type;
+struct of_meter_band_drop {
+    uint16_t        type == 1;
     uint16_t        len;
     uint32_t        rate;
     uint32_t        burst_size;
-    uint8_t[4]      pad;
+    pad(4);
 };
 
-struct ofp_meter_band_dscp_remark {
-    uint16_t        type;
+struct of_meter_band_dscp_remark {
+    uint16_t        type == 2;
     uint16_t        len;
     uint32_t        rate;
     uint32_t        burst_size;
     uint8_t         prec_level;
-    uint8_t[3]      pad;
+    pad(3);
 };
 
-struct ofp_meter_band_experimenter {
-    uint16_t        type;
+struct of_meter_band_experimenter {
+    uint16_t        type == 65535;
     uint16_t        len;
     uint32_t        rate;
     uint32_t        burst_size;
     uint32_t        experimenter;
 };
 
-struct ofp_meter_mod {
+struct of_meter_mod {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 29;
     uint16_t length;
     uint32_t xid;
     uint16_t command;
@@ -1127,9 +1121,9 @@
     list(of_meter_band_t) meters;
 };
 
-struct ofp_error_msg {
+struct of_error_msg {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 1;
     uint16_t length;
     uint32_t xid;
     uint16_t err_type;
@@ -1137,7 +1131,7 @@
     of_octets_t data;
 };
 
-//struct ofp_error_experimenter_msg {
+//struct of_error_experimenter_msg {
 //    uint8_t version;
 //    uint8_t type;
 //    uint16_t length;
@@ -1150,16 +1144,16 @@
 
 // STATS ENTRIES: flow, table, port, queue, group stats, group desc stats
 
-struct ofp_flow_stats_entry {
+struct of_flow_stats_entry {
     uint16_t length;
     uint8_t table_id;
-    uint8_t pad;
+    pad(1);
     uint32_t duration_sec;
     uint32_t duration_nsec;
     uint16_t priority;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
-    uint8_t[6] pad2;
+    pad(6);
     uint64_t cookie;
     uint64_t packet_count;
     uint64_t byte_count;
@@ -1168,17 +1162,17 @@
 };
 
 
-struct ofp_table_stats_entry {
+struct of_table_stats_entry {
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     uint32_t active_count;
     uint64_t lookup_count;
     uint64_t matched_count;
 };
 
-struct ofp_port_stats_entry {
+struct of_port_stats_entry {
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t rx_packets;
     uint64_t tx_packets;
     uint64_t rx_bytes;
@@ -1195,7 +1189,7 @@
     uint32_t duration_nsec;
 };
 
-struct ofp_queue_stats_entry {
+struct of_queue_stats_entry {
     of_port_no_t port_no;
     uint32_t queue_id;
     uint64_t tx_bytes;
@@ -1205,17 +1199,17 @@
     uint32_t duration_nsec;
 };
 
-struct ofp_bucket_counter {
+struct of_bucket_counter {
     uint64_t packet_count;
     uint64_t byte_count;
 };
 
-struct ofp_group_stats_entry {
+struct of_group_stats_entry {
     uint16_t length;
-    uint8_t[2] pad;
+    pad(2);
     uint32_t group_id;
     uint32_t ref_count;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t packet_count;
     uint64_t byte_count;
     uint32_t duration_sec;
@@ -1223,10 +1217,10 @@
     list(of_bucket_counter_t) bucket_stats;
 };
 
-struct ofp_group_desc_stats_entry {
+struct of_group_desc_stats_entry {
     uint16_t length;
     uint8_t type;
-    uint8_t pad;
+    pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
 };
@@ -1234,24 +1228,24 @@
 // STATS: 
 //  Desc, flow, agg, table, port, queue, group, group_desc, group_feat, experi
 
-struct ofp_desc_stats_request {
+struct of_desc_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_desc_stats_reply {
+struct of_desc_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 0;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_desc_str_t mfr_desc;
     of_desc_str_t hw_desc;
     of_desc_str_t sw_desc;
@@ -1259,182 +1253,182 @@
     of_desc_str_t dp_desc;
 };
 
-struct ofp_flow_stats_request {
+struct of_flow_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 1;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     of_port_no_t out_port;
     uint32_t out_group;
-    uint8_t[4] pad2;
+    pad(4);
     uint64_t cookie;
     uint64_t cookie_mask;
     of_match_t match;
 };
 
-struct ofp_flow_stats_reply {
+struct of_flow_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 1;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_flow_stats_entry_t) entries;
 };
 
-struct ofp_aggregate_stats_request {
+struct of_aggregate_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 2;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint8_t table_id;
-    uint8_t[3] pad;
+    pad(3);
     of_port_no_t out_port;
     uint32_t out_group;
-    uint8_t[4] pad2;
+    pad(4);
     uint64_t cookie;
     uint64_t cookie_mask;
     of_match_t match;
 };
 
-struct ofp_aggregate_stats_reply {
+struct of_aggregate_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 2;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t packet_count;
     uint64_t byte_count;
     uint32_t flow_count;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_table_stats_request {
+struct of_table_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 3;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_table_stats_reply {
+struct of_table_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 3;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_table_stats_entry_t) entries;
 };
 
 // FIXME: These are padded to 8 byte align beyond the length indicated
 
-struct ofp_table_feature_prop {
+struct of_table_feature_prop {
     uint16_t         type;
     uint16_t         length;
 };
 
-struct ofp_table_feature_prop_instructions {
-    uint16_t         type;
+struct of_table_feature_prop_instructions {
+    uint16_t         type == 0;
     uint16_t         length;
     // FIXME Check if instruction_t is right for ids here
     list(of_instruction_t)   instruction_ids;
 };
 
-struct ofp_table_feature_prop_instructions_miss {
-    uint16_t         type;
+struct of_table_feature_prop_instructions_miss {
+    uint16_t         type == 1;
     uint16_t         length;
     list(of_instruction_t)   instruction_ids;
 };
 
-struct ofp_table_feature_prop_next_tables {
-    uint16_t         type;
+struct of_table_feature_prop_next_tables {
+    uint16_t         type == 2;
     uint16_t         length;
     list(of_uint8_t) next_table_ids;
 };
 
-struct ofp_table_feature_prop_next_tables_miss {
-    uint16_t         type;
+struct of_table_feature_prop_next_tables_miss {
+    uint16_t         type == 3;
     uint16_t         length;
     list(of_uint8_t) next_table_ids;
 };
 
-struct ofp_table_feature_prop_write_actions {
-    uint16_t         type;
+struct of_table_feature_prop_write_actions {
+    uint16_t         type == 4;
     uint16_t         length;
     list(of_action_id_t) action_ids;
 };
 
-struct ofp_table_feature_prop_write_actions_miss {
-    uint16_t         type;
+struct of_table_feature_prop_write_actions_miss {
+    uint16_t         type == 5;
     uint16_t         length;
     list(of_action_id_t) action_ids;
 };
 
-struct ofp_table_feature_prop_apply_actions {
-    uint16_t         type;
+struct of_table_feature_prop_apply_actions {
+    uint16_t         type == 6;
     uint16_t         length;
     list(of_action_id_t) action_ids;
 };
 
-struct ofp_table_feature_prop_apply_actions_miss {
-    uint16_t         type;
+struct of_table_feature_prop_apply_actions_miss {
+    uint16_t         type == 7;
     uint16_t         length;
     list(of_action_id_t) action_ids;
 };
 
-struct ofp_table_feature_prop_match {
-    uint16_t         type;
+struct of_table_feature_prop_match {
+    uint16_t         type == 8;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct ofp_table_feature_prop_wildcards {
-    uint16_t         type;
+struct of_table_feature_prop_wildcards {
+    uint16_t         type == 10;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct ofp_table_feature_prop_write_setfield {
-    uint16_t         type;
+struct of_table_feature_prop_write_setfield {
+    uint16_t         type == 12;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct ofp_table_feature_prop_write_setfield_miss {
-    uint16_t         type;
+struct of_table_feature_prop_write_setfield_miss {
+    uint16_t         type == 13;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct ofp_table_feature_prop_apply_setfield {
-    uint16_t         type;
+struct of_table_feature_prop_apply_setfield {
+    uint16_t         type == 14;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct ofp_table_feature_prop_apply_setfield_miss {
-    uint16_t         type;
+struct of_table_feature_prop_apply_setfield_miss {
+    uint16_t         type == 15;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct ofp_table_feature_prop_experimenter {
-    uint16_t         type;
+struct of_table_feature_prop_experimenter {
+    uint16_t         type == 65535;
     uint16_t         length;
     uint32_t         experimenter;
     uint32_t         subtype;
@@ -1442,7 +1436,7 @@
 };
 
 // Not yet supported
-// struct ofp_table_feature_prop_experimenter_miss {
+// struct of_table_feature_prop_experimenter_miss {
 //     uint16_t         type;
 //     uint16_t         length;
 //     uint32_t         experimenter;
@@ -1450,10 +1444,10 @@
 //     of_octets_t      experimenter_data;
 // };
 
-struct ofp_table_features {
+struct of_table_features {
     uint16_t length;
     uint8_t table_id;
-    uint8_t[5] pad;
+    pad(5);
     of_table_name_t name;
     uint64_t metadata_match;
     uint64_t metadata_write;
@@ -1462,123 +1456,123 @@
     list(of_table_feature_prop_t) properties;
 };
 
-struct ofp_meter_features {
+struct of_meter_features {
     uint32_t    max_meter;
     uint32_t    band_types;
     uint32_t    capabilities;
     uint8_t     max_bands;
     uint8_t     max_color;
-    uint8_t[2]     pad;
+    pad(2);
 };
 
-struct ofp_port_stats_request {
+struct of_port_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 4;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_port_no_t port_no;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_port_stats_reply {
+struct of_port_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 4;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_port_stats_entry_t) entries;
 };
 
-struct ofp_queue_stats_request {
+struct of_queue_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 5;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_port_no_t port_no;
     uint32_t queue_id;
 };
 
-struct ofp_queue_stats_reply {
+struct of_queue_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 5;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_queue_stats_entry_t) entries;
 };
 
-struct ofp_group_stats_request {
+struct of_group_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 6;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t group_id;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_group_stats_reply {
+struct of_group_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 6;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_group_stats_entry_t) entries;
 };
 
-struct ofp_group_desc_stats_request {
+struct of_group_desc_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 7;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_group_desc_stats_reply {
+struct of_group_desc_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 7;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_group_desc_stats_entry_t) entries;
 };
 
-struct ofp_group_features_stats_request {
+struct of_group_features_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 8;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_group_features_stats_reply {
+struct of_group_features_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 8;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t types;
     uint32_t capabilities;
     uint32_t max_groups_all;
@@ -1591,131 +1585,131 @@
     uint32_t actions_ff;
 };
 
-struct ofp_meter_stats_request {
+struct of_meter_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 9;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t meter_id;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_meter_stats_reply {
+struct of_meter_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 9;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_meter_stats_t) entries;
 };
 
-struct ofp_meter_config_stats_request {
+struct of_meter_config_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 10;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t meter_id;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_meter_config_stats_reply {
+struct of_meter_config_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 10;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_meter_band_t) entries;
 };
 
 // FIXME stats added to get things working
-struct ofp_meter_features_stats_request {
+struct of_meter_features_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 11;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
 // FIXME stats added to get things working
-struct ofp_meter_features_stats_reply {
+struct of_meter_features_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 11;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     of_meter_features_t features;
 };
 
 // FIXME stats added to get things working
-struct ofp_table_features_stats_request {
+struct of_table_features_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 12;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_table_features_t) entries;
 };
 
 // FIXME stats added to get things working
-struct ofp_table_features_stats_reply {
+struct of_table_features_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 12;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_table_features_t) entries;
 };
 
 // FIXME stats added to get things working
-struct ofp_port_desc_stats_request {
+struct of_port_desc_stats_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 18;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 13;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
 };
 
 // FIXME stats added to get things working
-struct ofp_port_desc_stats_reply {
+struct of_port_desc_stats_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 19;
     uint16_t length;
     uint32_t xid;
-    uint16_t stats_type;
+    uint16_t stats_type == 13;
     uint16_t flags;
-    uint8_t[4] pad;
+    pad(4);
     list(of_port_desc_t) entries;
 };
 
-struct ofp_meter_band_stats {
+struct of_meter_band_stats {
     uint64_t        packet_band_count;
     uint64_t        byte_band_count;
 };
 
-struct ofp_meter_stats {
+struct of_meter_stats {
     uint32_t        meter_id;
     uint16_t        len;
-    uint8_t[6]         pad;
+    pad(6);
     uint32_t        flow_count;
     uint64_t        packet_in_count;
     uint64_t        byte_in_count;
@@ -1724,91 +1718,91 @@
     list(of_meter_band_stats_t) band_stats;
 };
 
-struct ofp_meter_config {
+struct of_meter_config {
     uint16_t        length;
     uint16_t        flags;
     uint32_t        meter_id;
     list(of_meter_band_t) entries;
 };
 
-struct ofp_experimenter_multipart_header {
+struct of_experimenter_multipart_header {
     uint32_t experimenter;
     uint32_t subtype;
 };
 
 // END OF STATS OBJECTS
 
-struct ofp_queue_prop {
+struct of_queue_prop {
     uint16_t type;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_queue_prop_min_rate {
-    uint16_t type;
+struct of_queue_prop_min_rate {
+    uint16_t type == 1;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint16_t rate;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_queue_prop_max_rate {
-    uint16_t type;
+struct of_queue_prop_max_rate {
+    uint16_t type == 2;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint16_t rate;
-    uint8_t[6] pad;
+    pad(6);
 };
 
-struct ofp_queue_prop_experimenter {
-    uint16_t type;
+struct of_queue_prop_experimenter {
+    uint16_t type == 65535;
     uint16_t len;
-    uint8_t[4] pad;
+    pad(4);
     uint32_t experimenter;
-    uint8_t[4] pad;
+    pad(4);
     of_octets_t data;
 };
 
-struct ofp_packet_queue {
+struct of_packet_queue {
     uint32_t queue_id;
     of_port_no_t port;
     uint16_t len;
-    uint8_t[6] pad;
+    pad(6);
     list(of_queue_prop_t) properties;
 };
 
-struct ofp_queue_get_config_request {
+struct of_queue_get_config_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 22;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port;
-    uint8_t[4] pad;
+    pad(4);
 };
 
-struct ofp_queue_get_config_reply {
+struct of_queue_get_config_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 23;
     uint16_t length;
     uint32_t xid;
     of_port_no_t port;
-    uint8_t[4] pad;
+    pad(4);
     list(of_packet_queue_t) queues;
 };
 
-struct ofp_role_request {
+struct of_role_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 24;
     uint16_t length;
     uint32_t xid;
     uint32_t role;
-    uint8_t[4] pad;
+    pad(4);
     uint64_t generation_id;
 };
 
-struct ofp_role_reply {
+struct of_role_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 25;
     uint16_t length;
     uint32_t xid;
     of_octets_t data;
@@ -1821,9 +1815,9 @@
 //   while uint32_t[1] is interest for slave
 ////////////////////////////////////////////////////////////////
 
-struct ofp_async_get_request {
+struct of_async_get_request {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 26;
     uint16_t length;
     uint32_t xid;
     uint32_t packet_in_mask_equal_master;
@@ -1834,9 +1828,9 @@
     uint32_t flow_removed_mask_slave;
 };
 
-struct ofp_async_get_reply {
+struct of_async_get_reply {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 27;
     uint16_t length;
     uint32_t xid;
     uint32_t packet_in_mask_equal_master;
@@ -1847,9 +1841,9 @@
     uint32_t flow_removed_mask_slave;
 };
 
-struct ofp_async_set {
+struct of_async_set {
     uint8_t version;
-    uint8_t type;
+    uint8_t type == 28;
     uint16_t length;
     uint32_t xid;
     uint32_t packet_in_mask_equal_master;
diff --git a/utest/test_frontend.py b/utest/test_frontend.py
new file mode 100755
index 0000000..1f284b0
--- /dev/null
+++ b/utest/test_frontend.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+# Copyright 2013, Big Switch Networks, Inc.
+#
+# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+# the following special exception:
+#
+# LOXI Exception
+#
+# As a special exception to the terms of the EPL, you may distribute libraries
+# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+# that copyright and licensing notices generated by LoxiGen are not altered or removed
+# from the LoxiGen Libraries and the notice provided below is (i) included in
+# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+# documentation for the LoxiGen Libraries, if distributed in binary form.
+#
+# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+#
+# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+# a copy of the EPL 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
+# EPL for the specific language governing permissions and limitations
+# under the EPL.
+
+import unittest
+import loxi_front_end.parser as parser
+import loxi_front_end.frontend as frontend
+from loxi_ir import *
+
+class FrontendTests(unittest.TestCase):
+    maxDiff = None
+
+    def test_simple(self):
+        ast = parser.parse("""
+#version 1
+
+enum ofp_port_config {
+    OFPPC_PORT_DOWN = 0x1,
+    OFPPC_NO_STP = 0x2,
+    OFPPC_NO_RECV = 0x4,
+    OFPPC_NO_RECV_STP = 0x8,
+    OFPPC_NO_FLOOD = 0x10,
+    OFPPC_NO_FWD = 0x20,
+    OFPPC_NO_PACKET_IN = 0x40,
+};
+
+#version 2
+
+struct of_echo_reply {
+    uint8_t version;
+    uint8_t type == 3;
+    uint16_t length;
+    uint32_t xid;
+    of_octets_t data;
+};
+
+enum ofp_queue_op_failed_code {
+    OFPQOFC_BAD_PORT = 0,
+    OFPQOFC_BAD_QUEUE = 1,
+    OFPQOFC_EPERM = 2,
+};
+
+struct of_packet_queue {
+    uint32_t queue_id;
+    uint16_t len;
+    pad(2);
+    list(of_queue_prop_t) properties;
+};
+""")
+
+        # Not testing the parser, just making sure the AST is what we expect
+        expected_ast = [
+            ['metadata', 'version', '1'],
+            ['enum', 'ofp_port_config', [
+                ['OFPPC_PORT_DOWN', 1],
+                ['OFPPC_NO_STP', 2],
+                ['OFPPC_NO_RECV', 4],
+                ['OFPPC_NO_RECV_STP', 8],
+                ['OFPPC_NO_FLOOD', 16],
+                ['OFPPC_NO_FWD', 32],
+                ['OFPPC_NO_PACKET_IN', 64]]],
+            ['metadata', 'version', '2'],
+            ['struct', 'of_echo_reply', [
+                ['data', 'uint8_t', 'version'],
+                ['type', 'uint8_t', 'type', 3],
+                ['data', 'uint16_t', 'length'],
+                ['data', 'uint32_t', 'xid'],
+                ['data', 'of_octets_t', 'data']]],
+            ['enum', 'ofp_queue_op_failed_code', [
+                ['OFPQOFC_BAD_PORT', 0],
+                ['OFPQOFC_BAD_QUEUE', 1],
+                ['OFPQOFC_EPERM', 2]]],
+            ['struct', 'of_packet_queue', [
+                ['data', 'uint32_t', 'queue_id'],
+                ['data', 'uint16_t', 'len'],
+                ['pad', 2],
+                ['data', 'list(of_queue_prop_t)', 'properties']]],
+        ]
+        self.assertEquals(expected_ast, ast)
+
+        ofinput = frontend.create_ofinput(ast)
+        self.assertEquals(set([1, 2]), ofinput.wire_versions)
+        expected_classes = [
+            OFClass('of_echo_reply', [
+                OFDataMember('version', 'uint8_t'), # XXX
+                OFTypeMember('type', 'uint8_t', 3),
+                OFLengthMember('length', 'uint16_t'),
+                OFDataMember('xid', 'uint32_t'),
+                OFDataMember('data', 'of_octets_t')]),
+            OFClass('of_packet_queue', [
+                OFDataMember('queue_id', 'uint32_t'),
+                OFLengthMember('len', 'uint16_t'),
+                OFPadMember(2),
+                OFDataMember('properties', 'list(of_queue_prop_t)')]),
+        ]
+        self.assertEquals(expected_classes, ofinput.classes)
+        expected_enums = [
+            OFEnum('ofp_port_config', [
+                ('OFPPC_PORT_DOWN', 1),
+                ('OFPPC_NO_STP', 2),
+                ('OFPPC_NO_RECV', 4),
+                ('OFPPC_NO_RECV_STP', 8),
+                ('OFPPC_NO_FLOOD', 16),
+                ('OFPPC_NO_FWD', 32),
+                ('OFPPC_NO_PACKET_IN', 64)]),
+            OFEnum('ofp_queue_op_failed_code', [
+                ('OFPQOFC_BAD_PORT', 0),
+                ('OFPQOFC_BAD_QUEUE', 1),
+                ('OFPQOFC_EPERM', 2)]),
+        ]
+        self.assertEquals(expected_enums, ofinput.enums)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/utest/test_parser.py b/utest/test_parser.py
index 89dae10..cb22a9c 100755
--- a/utest/test_parser.py
+++ b/utest/test_parser.py
@@ -36,7 +36,7 @@
 struct foo { };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(), [['struct', 'foo', []]])
+        self.assertEquals(ast, [['struct', 'foo', []]])
 
     def test_one_field(self):
         src = """\
@@ -45,8 +45,8 @@
 };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(),
-            [['struct', 'foo', [['uint32_t', 'bar']]]])
+        self.assertEquals(ast,
+            [['struct', 'foo', [['data', 'uint32_t', 'bar']]]])
 
     def test_multiple_fields(self):
         src = """\
@@ -57,11 +57,11 @@
 };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(),
+        self.assertEquals(ast,
             [['struct', 'foo',
-                [['uint32_t', 'bar'],
-                 ['uint8_t', 'baz'],
-                 ['uint64_t', 'abc']]]])
+                [['data', 'uint32_t', 'bar'],
+                 ['data', 'uint8_t', 'baz'],
+                 ['data', 'uint64_t', 'abc']]]])
 
     def test_array_type(self):
         src = """\
@@ -70,8 +70,8 @@
 };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(),
-            [['struct', 'foo', [['uint32_t[4]', 'bar']]]])
+        self.assertEquals(ast,
+            [['struct', 'foo', [['data', 'uint32_t[4]', 'bar']]]])
 
     def test_list_type(self):
         src = """\
@@ -80,8 +80,28 @@
 };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(),
-            [['struct', 'foo', [['list(of_action_t)', 'bar']]]])
+        self.assertEquals(ast,
+            [['struct', 'foo', [['data', 'list(of_action_t)', 'bar']]]])
+
+    def test_pad_member(self):
+        src = """\
+struct foo {
+    pad(1);
+};
+"""
+        ast = parser.parse(src)
+        self.assertEquals(ast,
+            [['struct', 'foo', [['pad', 1]]]])
+
+    def test_type_member(self):
+        src = """\
+struct foo {
+    uint16_t foo == 0x10;
+};
+"""
+        ast = parser.parse(src)
+        self.assertEquals(ast,
+            [['struct', 'foo', [['type', 'uint16_t', 'foo', 0x10]]]])
 
 class EnumTests(unittest.TestCase):
     def test_empty(self):
@@ -90,7 +110,7 @@
 };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(), [['enum', 'foo', []]])
+        self.assertEquals(ast, [['enum', 'foo', []]])
 
     def test_one(self):
         src = """\
@@ -99,7 +119,7 @@
 };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(), [['enum', 'foo', [['BAR', 1]]]])
+        self.assertEquals(ast, [['enum', 'foo', [['BAR', 1]]]])
 
     def test_multiple(self):
         src = """\
@@ -110,7 +130,7 @@
 };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(), [['enum', 'foo', [['OFP_A', 1], ['OFP_B', 2], ['OFP_C', 3]]]])
+        self.assertEquals(ast, [['enum', 'foo', [['OFP_A', 1], ['OFP_B', 2], ['OFP_C', 3]]]])
 
     def test_trailing_comma(self):
         src = """\
@@ -121,7 +141,7 @@
 };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(), [['enum', 'foo', [['OFP_A', 1], ['OFP_B', 2], ['OFP_C', 3]]]])
+        self.assertEquals(ast, [['enum', 'foo', [['OFP_A', 1], ['OFP_B', 2], ['OFP_C', 3]]]])
 
 class TestMetadata(unittest.TestCase):
     def test_version(self):
@@ -129,7 +149,7 @@
 #version 1
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(), [['metadata', 'version', '1']])
+        self.assertEquals(ast, [['metadata', 'version', '1']])
 
 class TestToplevel(unittest.TestCase):
     def test_multiple_structs(self):
@@ -138,7 +158,7 @@
 struct bar { };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(),
+        self.assertEquals(ast,
             [['struct', 'foo', []], ['struct', 'bar', []]])
 
     def test_comments(self):
@@ -152,8 +172,8 @@
 // comment 4
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(),
-            [['struct', 'foo', [['uint32_t', 'a']]]])
+        self.assertEquals(ast,
+            [['struct', 'foo', [['data', 'uint32_t', 'a']]]])
 
     def test_mixed(self):
         src = """\
@@ -163,7 +183,7 @@
 struct bar { };
 """
         ast = parser.parse(src)
-        self.assertEquals(ast.asList(),
+        self.assertEquals(ast,
             [['metadata', 'version', '1'],
              ['struct', 'foo', []],
              ['metadata', 'version', '2'],