Initial import

LoxiGen is the work of several developers, not just myself.
diff --git a/c_gen/templates/of_wire_buf.h b/c_gen/templates/of_wire_buf.h
new file mode 100644
index 0000000..cf1ee17
--- /dev/null
+++ b/c_gen/templates/of_wire_buf.h
@@ -0,0 +1,884 @@
+:: # 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.
+::
+/* Copyright 2013, Big Switch Networks, Inc. */
+
+#if !defined(_OF_WIRE_BUF_H_)
+#define _OF_WIRE_BUF_H_
+
+#include <string.h>
+#include <loci/loci_base.h>
+#include <loci/of_object.h>
+#include <loci/of_match.h>
+#include <loci/of_buffer.h>
+
+/****************************************************************
+ *
+ * Wire buffer declaration, constructor, data alloc, delete
+ *
+ ****************************************************************/
+
+/* Maximum length of an OpenFlow message. All wire buffers allocated for
+ * new objects (that don't come from a message) are this length to avoid
+ * needing to grow the buffers. */
+#define OF_WIRE_BUFFER_MAX_LENGTH 65535
+
+/**
+ * Buffer management structure
+ */
+typedef struct of_wire_buffer_s {
+    /** Pointer to a monolithic data buffer */
+    uint8_t *buf;
+
+    /** Length of buffer actually allocated */
+    int alloc_bytes;
+    /** Current extent actually used */
+    int current_bytes;
+    /** If not NULL, use this to dealloc buf */
+    of_buffer_free_f free;
+} of_wire_buffer_t;
+
+/**
+ * Decouples object from underlying wire buffer
+ *
+ * Called a 'slice' in some places.
+ */
+typedef struct of_wire_object_s {
+    /** A pointer to the underlying buffer's management structure. */
+    of_wire_buffer_t *wbuf;  
+    /** The start offset for this object relative to the start of the
+     * underlying buffer */
+    int obj_offset;
+    /* Boolean, whether the object owns the wire buffer. */
+    char owned;
+} of_wire_object_t;
+
+#define WBUF_BUF(wbuf) (wbuf)->buf
+#define WBUF_ALLOC_BYTES(wbuf) (wbuf)->alloc_bytes
+#define WBUF_CURRENT_BYTES(wbuf) (wbuf)->current_bytes
+
+/**
+ * For read access, throw an error code if current buffer
+ * is not big enough.
+ * @param wbuf Pointer to an of_wire_buffer_t structure
+ * @param offset The extent of the buffer required
+ */
+#define OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset)                      \
+    ASSERT(((wbuf) != NULL) && (WBUF_BUF(wbuf) != NULL) &&             \
+           (offset > 0) && (WBUF_CURRENT_BYTES(wbuf) >= offset))
+
+/*
+ * Index a wire buffer
+ * Index a wire object (from obj_offset)
+ * Index a LOCI object
+ */
+
+/**
+ * Return a pointer to a particular offset in a wire buffer's data
+ * @param wbuf Pointer to an of_wire_buffer_t structure
+ * @param offset The location to reference
+ */
+#define OF_WIRE_BUFFER_INDEX(wbuf, offset) (&((WBUF_BUF(wbuf))[offset]))
+
+/**
+ * Return a pointer to a particular offset in the underlying buffer
+ * associated with a wire object
+ * @param wobj Pointer to an of_wire_object_t structure
+ * @param offset The location to reference relative to the start of the object
+ */
+#define OF_WIRE_OBJECT_INDEX(wobj, offset) \
+    OF_WIRE_BUFFER_INDEX((wobj)->wbuf, (offset) + (wobj)->obj_offset)
+
+/****************************************************************
+ * Object specific macros; of_object_t includes a wire_object
+ ****************************************************************/
+
+/**
+ * Return a pointer to a particular offset in the underlying buffer
+ * associated with a wire object
+ * @param obj Pointer to an of_object_t object
+ * @param offset The location to reference relative to the start of the object
+ */
+#define OF_OBJECT_BUFFER_INDEX(obj, offset) \
+    OF_WIRE_OBJECT_INDEX(&((obj)->wire_object), offset)
+
+/**
+ * Return the absolute offset as an integer from a object-relative offset
+ * @param obj Pointer to an of_wire_object_t structure
+ * @param offset The location to reference relative to the start of the object
+ */
+#define OF_OBJECT_ABSOLUTE_OFFSET(obj, offset) \
+    ((obj)->wire_object.obj_offset + offset)
+
+
+/**
+ * Map a generic object to the underlying wire buffer object (not the octets)
+ *
+ * Treat as private
+ */
+#define OF_OBJECT_TO_WBUF(obj) ((obj)->wire_object.wbuf)
+
+
+
+/**
+ * Minimum allocation size for wire buffer object
+ */
+#define OF_WIRE_BUFFER_MIN_ALLOC_BYTES 128
+
+/**
+ * Allocate a wire buffer object and the underlying data buffer.
+ * The wire buffer is initally empty (current_bytes == 0).
+ * @param a_bytes The number of bytes to allocate.
+ * @returns A wire buffer object if successful or NULL
+ */
+static inline of_wire_buffer_t *
+of_wire_buffer_new(int a_bytes)
+{
+    of_wire_buffer_t *wbuf;
+
+    wbuf = (of_wire_buffer_t *)MALLOC(sizeof(of_wire_buffer_t));
+    if (wbuf == NULL) {
+        return NULL;
+    }
+    MEMSET(wbuf, 0, sizeof(of_wire_buffer_t));
+
+    if (a_bytes < OF_WIRE_BUFFER_MIN_ALLOC_BYTES) {
+        a_bytes = OF_WIRE_BUFFER_MIN_ALLOC_BYTES;
+    }
+
+    if ((wbuf->buf = (uint8_t *)MALLOC(a_bytes)) == NULL) {
+        FREE(wbuf);
+        return NULL;
+    }
+    MEMSET(wbuf->buf, 0, a_bytes);
+    wbuf->current_bytes = 0;
+    wbuf->alloc_bytes = a_bytes;
+
+    return (of_wire_buffer_t *)wbuf;
+}
+
+/**
+ * Allocate a wire buffer object and bind it to an existing buffer.
+ * @param buf       Existing buffer.
+ * @param bytes     Size of buf.
+ * @param buf_free  Function called to deallocate buf.
+ * @returns A wire buffer object if successful or NULL
+ */
+static inline of_wire_buffer_t *
+of_wire_buffer_new_bind(uint8_t *buf, int bytes, of_buffer_free_f buf_free)
+{
+    of_wire_buffer_t *wbuf;
+
+    wbuf = (of_wire_buffer_t *)MALLOC(sizeof(of_wire_buffer_t));
+    if (wbuf == NULL) {
+        return NULL;
+    }
+
+    wbuf->buf = buf;
+    wbuf->free = buf_free;
+    wbuf->current_bytes = bytes;
+    wbuf->alloc_bytes = bytes;
+
+    return (of_wire_buffer_t *)wbuf;
+}
+
+static inline void
+of_wire_buffer_free(of_wire_buffer_t *wbuf)
+{
+    if (wbuf == NULL) return;
+
+    if (wbuf->buf != NULL) {
+        if (wbuf->free != NULL) {
+            wbuf->free(wbuf->buf);
+        } else {
+            FREE(wbuf->buf);
+        }
+    }
+
+    FREE(wbuf);
+}
+
+static inline void
+of_wire_buffer_steal(of_wire_buffer_t *wbuf, uint8_t **buffer)
+{
+    *buffer = wbuf->buf;
+    /* Mark underlying data buffer as taken */
+    wbuf->buf = NULL;
+    of_wire_buffer_free(wbuf);
+}
+
+/**
+ * Increase the currently used length of the wire buffer.
+ * Will fail an assertion if the allocated length is not long enough.
+ *
+ * @param wbuf Pointer to the wire buffer structure
+ * @param bytes Total number of bytes buffer should grow to
+ */
+
+static inline void
+of_wire_buffer_grow(of_wire_buffer_t *wbuf, int bytes)
+{
+    ASSERT(wbuf != NULL);
+    ASSERT(wbuf->alloc_bytes >= bytes);
+    if (bytes > wbuf->current_bytes) {
+        wbuf->current_bytes = bytes;
+    }
+}
+
+/* TBD */
+
+
+/**
+ * Get a uint8_t scalar from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to put value
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_u8_get(of_wire_buffer_t *wbuf, int offset, uint8_t *value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint8_t));
+    buf_u8_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
+}
+
+/**
+ * Set a uint8_t scalar in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value The value to store
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_u8_set(of_wire_buffer_t *wbuf, int offset, uint8_t value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint8_t));
+    buf_u8_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
+}
+
+/**
+ * Get a uint16_t scalar from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to put value
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_u16_get(of_wire_buffer_t *wbuf, int offset, uint16_t *value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint16_t));
+    buf_u16_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
+}
+
+/**
+ * Set a uint16_t scalar in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value The value to store
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_u16_set(of_wire_buffer_t *wbuf, int offset, uint16_t value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint16_t));
+    buf_u16_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
+}
+
+/**
+ * Get a uint32_t scalar from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to put value
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_u32_get(of_wire_buffer_t *wbuf, int offset, uint32_t *value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint32_t));
+    buf_u32_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
+}
+
+/**
+ * Set a uint32_t scalar in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value The value to store
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_u32_set(of_wire_buffer_t *wbuf, int offset, uint32_t value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint32_t));
+    buf_u32_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
+}
+
+/**
+ * Get a uint64_t scalar from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to put value
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_u64_get(of_wire_buffer_t *wbuf, int offset, uint64_t *value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint64_t));
+    buf_u64_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
+}
+
+/**
+ * Set a uint64_t scalar in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value The value to store
+ *
+ * The underlying buffer accessor funtions handle endian and alignment.
+ */
+
+static inline void
+of_wire_buffer_u64_set(of_wire_buffer_t *wbuf, int offset, uint64_t value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint64_t));
+    buf_u64_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
+}
+
+/**
+ * Get a generic OF match structure from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to the structure to update
+ *
+ * NOT IMPLEMENTED.
+ *
+ */
+
+static inline void
+of_wire_buffer_match_get(int version, of_wire_buffer_t *wbuf, int offset,
+                      of_match_t *value)
+{
+    ASSERT(0);
+}
+
+/**
+ * Set a generic OF match structure in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to the structure to store
+ *
+ * NOT IMPLEMENTED.
+ *
+ */
+
+static inline void
+of_wire_buffer_match_set(int version, of_wire_buffer_t *wbuf, int offset,
+                      of_match_t *value)
+{
+    ASSERT(0);
+}
+
+/**
+ * Get a port description object from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to the structure to fill out
+ *
+ * NOT IMPLEMENTED.
+ *
+ * @fixme Where should this go?
+ */
+
+static inline void
+of_wire_buffer_of_port_desc_get(int version, of_wire_buffer_t *wbuf, int offset,
+                             void *value)
+{
+    ASSERT(0);
+}
+
+/**
+ * Set a port description object in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to the structure to fill out
+ *
+ * NOT IMPLEMENTED.
+ *
+ * @fixme Where should this go?
+ */
+
+static inline void
+of_wire_buffer_of_port_desc_set(int version, of_wire_buffer_t *wbuf, int offset,
+                             void *value)
+{
+    ASSERT(0);
+}
+
+/**
+ * Get a port number scalar from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to put value
+ *
+ * Port numbers are version specific.
+ */
+
+static inline void
+of_wire_buffer_port_no_get(int version, of_wire_buffer_t *wbuf, int offset,
+                        of_port_no_t *value)
+{
+    uint16_t v16;
+    uint32_t v32;
+
+    switch (version) {
+    case OF_VERSION_1_0:
+        of_wire_buffer_u16_get(wbuf, offset, &v16);
+        *value = v16;
+        break;
+    case OF_VERSION_1_1:
+    case OF_VERSION_1_2:
+    case OF_VERSION_1_3:
+        of_wire_buffer_u32_get(wbuf, offset, &v32);
+        *value = v32;
+        break;
+    default:
+        ASSERT(0);
+    }
+}
+
+/**
+ * Set a port number scalar from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value The value to store in the buffer
+ *
+ * Port numbers are version specific.
+ */
+
+static inline void
+of_wire_buffer_port_no_set(int version, of_wire_buffer_t *wbuf, int offset,
+                      of_port_no_t value)
+{
+
+    switch (version) {
+    case OF_VERSION_1_0:
+        of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
+        break;
+    case OF_VERSION_1_1:
+    case OF_VERSION_1_2:
+    case OF_VERSION_1_3:
+        of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
+        break;
+    default:
+        ASSERT(0);
+    }
+}
+
+/**
+ * Get a flow mod command value from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to put value
+ */
+
+static inline void
+of_wire_buffer_fm_cmd_get(int version, of_wire_buffer_t *wbuf, int offset,
+                        of_fm_cmd_t *value)
+{
+    uint16_t v16;
+    uint8_t v8;
+
+    switch (version) {
+    case OF_VERSION_1_0:
+        of_wire_buffer_u16_get(wbuf, offset, &v16);
+        *value = v16;
+        break;
+    case OF_VERSION_1_1:
+    case OF_VERSION_1_2:
+    case OF_VERSION_1_3:
+        of_wire_buffer_u8_get(wbuf, offset, &v8);
+        *value = v8;
+        break;
+    default:
+        ASSERT(0);
+    }
+}
+
+/**
+ * Set a flow mod command value in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value The value to store
+ */
+
+static inline void
+of_wire_buffer_fm_cmd_set(int version, of_wire_buffer_t *wbuf, int offset,
+                      of_fm_cmd_t value)
+{
+    switch (version) {
+    case OF_VERSION_1_0:
+        of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
+        break;
+    case OF_VERSION_1_1:
+    case OF_VERSION_1_2:
+    case OF_VERSION_1_3:
+        of_wire_buffer_u8_set(wbuf, offset, (uint8_t)value);
+        break;
+    default:
+        ASSERT(0);
+    }
+}
+
+/**
+ * Get a wild card bitmap value from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to store the value
+ */
+
+static inline void
+of_wire_buffer_wc_bmap_get(int version, of_wire_buffer_t *wbuf, int offset,
+                        of_wc_bmap_t *value)
+{
+    uint32_t v32;
+    uint64_t v64;
+
+    switch (version) {
+    case OF_VERSION_1_0:
+    case OF_VERSION_1_1:
+        of_wire_buffer_u32_get(wbuf, offset, &v32);
+        *value = v32;
+        break;
+    case OF_VERSION_1_2:
+    case OF_VERSION_1_3:
+        of_wire_buffer_u64_get(wbuf, offset, &v64);
+        *value = v64;
+        break;
+    default:
+        ASSERT(0);
+    }
+}
+
+/**
+ * Set a wild card bitmap value in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value The value to store
+ */
+
+static inline void
+of_wire_buffer_wc_bmap_set(int version, of_wire_buffer_t *wbuf, int offset,
+                      of_wc_bmap_t value)
+{
+    switch (version) {
+    case OF_VERSION_1_0:
+    case OF_VERSION_1_1:
+        of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
+        break;
+    case OF_VERSION_1_2:
+    case OF_VERSION_1_3:
+        of_wire_buffer_u64_set(wbuf, offset, (uint64_t)value);
+        break;
+    default:
+        ASSERT(0);
+    }
+}
+
+/* match bitmap and wildcard bitmaps followed the same pattern */
+#define of_wire_buffer_match_bmap_get of_wire_buffer_wc_bmap_get
+#define of_wire_buffer_match_bmap_set of_wire_buffer_wc_bmap_set
+
+/* Derived functions, mostly for fixed length name strings */
+#define of_wire_buffer_char_get of_wire_buffer_u8_get
+#define of_wire_buffer_char_set of_wire_buffer_u8_set
+
+
+/**
+ * Get an octet object from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to where to put value
+ *
+ * of_octets_t is treated specially as the high level functions pass around
+ * pointers for "get" operators.
+ *
+ * Important: The length of data to copy is stored in the value->bytes
+ * variable.
+ */
+
+static inline void
+of_wire_buffer_octets_data_get(of_wire_buffer_t *wbuf, int offset,
+                               of_octets_t *value)
+{
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + OF_OCTETS_BYTES_GET(value));
+    buf_octets_get(OF_WIRE_BUFFER_INDEX(wbuf, offset),
+                   OF_OCTETS_POINTER_GET(value),
+                   OF_OCTETS_BYTES_GET(value));
+}
+
+/**
+ * Set an octet object in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param value Pointer to the octet stream to store
+ * @param cur_len Current length of data in the buffer
+ *
+ * of_octets_t is treated specially as the high level functions pass around
+ * pointers for "get" operators.
+ *
+ * @fixme Need to take into account cur_len
+ */
+
+static inline void
+of_wire_buffer_octets_data_set(of_wire_buffer_t *wbuf, int offset,
+                               of_octets_t *value, int cur_len)
+{
+    // FIXME need to adjust length of octets member in buffer
+    ASSERT(cur_len == 0 || cur_len == value->bytes);
+
+    OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + OF_OCTETS_BYTES_GET(value));
+    buf_octets_set(OF_WIRE_BUFFER_INDEX(wbuf, offset),
+                   OF_OCTETS_POINTER_GET(value),
+                   OF_OCTETS_BYTES_GET(value));
+}
+
+static inline void
+_wbuf_octets_set(of_wire_buffer_t *wbuf, int offset, uint8_t *src, int bytes) {
+    of_octets_t octets;
+    OF_OCTETS_POINTER_SET(&octets, src);
+    OF_OCTETS_BYTES_SET(&octets, bytes);
+    of_wire_buffer_octets_data_set(wbuf, offset, &octets, bytes);
+}
+
+static inline void
+_wbuf_octets_get(of_wire_buffer_t *wbuf, int offset, uint8_t *dst, int bytes) {
+    of_octets_t octets;
+    OF_OCTETS_POINTER_SET(&octets, dst);
+    OF_OCTETS_BYTES_SET(&octets, bytes);
+    of_wire_buffer_octets_data_get(wbuf, offset, &octets);
+}
+
+
+/**
+ * Get a MAC address from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param mac Pointer to the mac address location
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_mac_get(buf, offset, mac) \
+    _wbuf_octets_get(buf, offset, (uint8_t *)mac, 6)
+
+/**
+ * Set a MAC address in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param mac The variable holding the mac address to store
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_mac_set(buf, offset, mac) \
+    _wbuf_octets_set(buf, offset, (uint8_t *)&mac, 6)
+
+
+/**
+ * Get a port name string from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param mac The mac address
+ *
+ * Uses the octets function.
+ */
+#define of_wire_buffer_port_name_get(buf, offset, portname) \
+    _wbuf_octets_get(buf, offset, (uint8_t *)portname, \
+                           OF_MAX_PORT_NAME_LEN)
+
+/**
+ * Set a port name address in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param portname Where to store the port name
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_port_name_set(buf, offset, portname) \
+    _wbuf_octets_set(buf, offset, (uint8_t *)portname, \
+                           OF_MAX_PORT_NAME_LEN)
+
+
+/**
+ * Get a table name string from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param portname The port name
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_tab_name_get(buf, offset, tabname) \
+    _wbuf_octets_get(buf, offset, (uint8_t *)tabname, \
+                           OF_MAX_TABLE_NAME_LEN)
+
+/**
+ * Set a table name address in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param mac Where to store the table name
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_tab_name_set(buf, offset, tabname) \
+    _wbuf_octets_set(buf, offset, (uint8_t *)tabname, \
+                           OF_MAX_TABLE_NAME_LEN)
+
+/**
+ * Get a description string from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param desc Where to store the description string
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_desc_str_get(buf, offset, desc) \
+    _wbuf_octets_get(buf, offset, (uint8_t *)desc, OF_DESC_STR_LEN)
+
+/**
+ * Set a description string in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param desc The description string
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_desc_str_set(buf, offset, desc) \
+    _wbuf_octets_set(buf, offset, (uint8_t *)desc, OF_DESC_STR_LEN)
+
+/**
+ * Get a serial number string from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param sernum Where to store the serial number string
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_ser_num_get(buf, offset, sernum) \
+    _wbuf_octets_get(buf, offset, (uint8_t *)sernum, OF_SERIAL_NUM_LEN)
+
+/**
+ * Set a serial number string in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param desc The serial number string
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_ser_num_set(buf, offset, sernum) \
+    _wbuf_octets_set(buf, offset, (uint8_t *)sernum, OF_SERIAL_NUM_LEN)
+
+/**
+ * Get an ipv6 address from a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param addr Pointer to where to store the ipv6 address
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_ipv6_get(buf, offset, addr) \
+    _wbuf_octets_get(buf, offset, (uint8_t *)addr, sizeof(of_ipv6_t))
+
+/**
+ * Set an ipv6 address in a wire buffer
+ * @param wbuf The pointer to the wire buffer structure
+ * @param offset Offset in the wire buffer
+ * @param addr The variable holding ipv6 address to store
+ *
+ * Uses the octets function.
+ */
+
+#define of_wire_buffer_ipv6_set(buf, offset, addr) \
+    _wbuf_octets_set(buf, offset, (uint8_t *)&addr, sizeof(of_ipv6_t))
+
+/* Relocate data from start offset to the end of the buffer to a new position */
+static inline void
+of_wire_buffer_move_end(of_wire_buffer_t *wbuf, int start_offset, int new_offset)
+{
+    int bytes;
+    int new_length;
+
+    if (new_offset > start_offset) {
+        bytes =  new_offset - start_offset;
+        new_length = wbuf->alloc_bytes + bytes;
+        OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, new_length);
+    } else {
+        bytes =  start_offset - new_offset;
+        new_length = wbuf->alloc_bytes - bytes;
+    }
+
+    MEMMOVE(&wbuf->buf[new_offset], &wbuf->buf[start_offset], bytes);
+    wbuf->alloc_bytes = new_length;
+}
+
+/* Given a wire buffer object and the offset of the start of an of_match struct,
+ * return its total length in the buffer
+ */
+static inline int
+of_match_bytes(of_wire_buffer_t *wbuf, int offset) {
+    uint16_t len;
+    of_wire_buffer_u16_get(wbuf, offset + 2, &len);
+    return OF_MATCH_BYTES(len);
+}
+
+extern void
+of_wire_buffer_replace_data(of_wire_buffer_t *wbuf, 
+                            int offset, 
+                            int old_len,
+                            uint8_t *data,
+                            int new_len);
+
+#endif /* _OF_WIRE_BUF_H_ */