diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | include/ouroboros/du_buff.h | 50 | ||||
| -rw-r--r-- | include/ouroboros/logs.h | 2 | ||||
| -rw-r--r-- | src/lib/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/lib/du_buff.c | 367 | 
5 files changed, 421 insertions, 1 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ca05c95..efbc3706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1.0) +cmake_minimum_required(VERSION 3.0.0)  set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")  #set(CMAKE_VERBOSE_MAKEFILE ON) diff --git a/include/ouroboros/du_buff.h b/include/ouroboros/du_buff.h new file mode 100644 index 00000000..d23f4b09 --- /dev/null +++ b/include/ouroboros/du_buff.h @@ -0,0 +1,50 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Data Unit Buffer + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_DU_BUFF_H +#define OUROBOROS_DU_BUFF_H + +#include "common.h" +#include "list.h" + +struct du_buff; + +typedef struct du_buff du_buff_t; + +du_buff_t * du_buff_create(size_t size); +void        du_buff_destroy(du_buff_t * dub); + +int         du_buff_init(du_buff_t * dub, +                         size_t      start, +                         uint8_t   * data, +                         size_t      len); + +uint8_t   * du_buff_data_ptr_start(du_buff_t * dub); +uint8_t   * du_buff_data_ptr_end(du_buff_t * dub); + +int         du_buff_head_alloc(du_buff_t * dub, size_t size); +int         du_buff_tail_alloc(du_buff_t * dub, size_t size); +int         du_buff_head_release(du_buff_t * dub, size_t size); +int         du_buff_tail_release(du_buff_t * dub, size_t size); + +#endif /* OUROBOROS_DU_BUFF_H */ diff --git a/include/ouroboros/logs.h b/include/ouroboros/logs.h index c72fb9ae..6f9986dc 100644 --- a/include/ouroboros/logs.h +++ b/include/ouroboros/logs.h @@ -43,6 +43,8 @@  #define LOG_DBG(FMT,   ARGS...) do { } while (0)  #endif +#define LOG_DBGF(FMT,  ARGS...) LOG_DBG("%s: " FMT, __FUNCTION__, ##ARGS) +  #define LOG_MISSING LOG_ERR("Missing code in %s:%d",__FILE__, __LINE__)  #endif diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 5c0e6bbe..9a6f1946 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCE_FILES          # Add source files here          bitmap.c          cdap.c +        du_buff.c  )  add_library(ouroboros SHARED ${SOURCE_FILES}) diff --git a/src/lib/du_buff.c b/src/lib/du_buff.c new file mode 100644 index 00000000..84bf528c --- /dev/null +++ b/src/lib/du_buff.c @@ -0,0 +1,367 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Data Unit Buffer + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <malloc.h> +#include <string.h> +#include <errno.h> +#include "ouroboros/du_buff.h" + +#define OUROBOROS_PREFIX "du_buff" + +#include "ouroboros/logs.h" + +struct buffer { +        uint8_t        * data; +        size_t           size; +        struct list_head list; +}; + +struct du_buff { +        struct buffer  * buffer; +        size_t           size; +        size_t           du_start; +        size_t           du_end; +        struct list_head list; +}; + +void buffer_destroy(struct buffer * buf) +{ +        if (buf == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return; +        } + +        list_del(&(buf->list)); + +        free (&(buf->data)); + +        free (buf); +} + + +void buffer_destroy_list(struct buffer * buf) +{ +        struct list_head * ptr; +        struct list_head * n; + +        if (buf == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return; +        } + +        list_for_each_safe(ptr, n, &(buf->list)) { +                struct buffer * tmp = list_entry(ptr, struct buffer, list); +                list_del(ptr); +                buffer_destroy(tmp); +        } +} + +struct buffer * buffer_create (size_t size) +{ +        struct buffer * head      = NULL; +        size_t          remaining = size; +        const size_t    page_size = sysconf(_SC_PAGESIZE); + +        while (remaining > 0) { +                struct buffer * buf; +                size_t sz = remaining < page_size ? remaining : page_size; + +                buf = (struct buffer *) malloc(sizeof(struct buffer)); +                if (buf == NULL) { +                        LOG_WARN("Could not allocate struct."); +                        return NULL; +                } + +                buf->data = (uint8_t *) malloc(sz); +                if (buf->data == NULL) { +                        LOG_WARN("Could not allocate memory block."); +                        buffer_destroy_list(head); +                        return NULL; +                } + +                buf->size = sz; +                INIT_LIST_HEAD(&(buf->list)); + +                if (head == NULL) +                        head = buf; +                else +                        list_add_tail(&(buf->list), &(head->list)); + +                remaining -= buf->size; +        } + +        return head; +} + +struct buffer * buffer_seek(const struct buffer * head, size_t pos) +{ +        struct list_head * ptr = NULL; +        struct buffer    * hit = NULL; +        size_t cur_buf_start   = 0; +        size_t cur_buf_end     = 0; + +        if (head = NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return NULL; +        } + +        list_for_each(ptr, &(head->list)) { +                struct buffer * tmp = list_entry(ptr, struct buffer, list); + +                cur_buf_end = cur_buf_start + tmp->size; + +                if (cur_buf_end > pos) +                        return tmp; + +                cur_buf_start = cur_buf_end; +        } + +        return NULL; +} + +uint8_t * buffer_seek_pos(const struct buffer * head, size_t pos) +{ +        struct list_head * ptr = NULL; +        struct buffer    * hit = NULL; +        size_t cur_buf_start   = 0; +        size_t cur_buf_end     = 0; + +        if (head = NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return NULL; +        } + +        list_for_each(ptr, &(head->list)) { +                struct buffer * tmp = list_entry(ptr, struct buffer, list); + +                cur_buf_end = cur_buf_start + tmp->size; + +                if (cur_buf_end > pos) +                        return tmp->data + (pos - cur_buf_start); + +                cur_buf_start = cur_buf_end; +        } + +        return NULL; +} + +int buffer_copy_data(struct buffer * head, +                     size_t          pos, +                     const void    * src, +                     size_t          len) +{ +        struct list_head * ptr       = NULL; +        struct buffer    * buf_start = NULL; +        struct buffer    * buf_end   = NULL; +        uint8_t          * ptr_start = NULL; +        size_t             space_in_buf; +        size_t             bytes_remaining; +        uint8_t          * copy_pos  = NULL; + +        if (head == NULL || src == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return -EINVAL; +        } + +        buf_start = buffer_seek(head, pos); +        buf_end   = buffer_seek(head, pos + len); + +        if (buf_start == NULL || buf_end == NULL) { +                LOG_DBGF("Index out of bounds %d, %d", +                        pos, +                        pos+len); +                return -EINVAL; +        } + +        ptr_start = buffer_seek_pos(head, pos); + +        if (buf_start == buf_end) { +                memcpy(ptr_start, src, len); +                return 0; +        } + +        copy_pos = (uint8_t *)src; +        bytes_remaining = len; +        list_for_each(ptr, &(buf_start->list)) { +                struct buffer * tmp = list_entry(ptr, struct buffer, list); +                space_in_buf = tmp->data + tmp->size - ptr_start; +                if (space_in_buf >= bytes_remaining) { +                        memcpy(ptr_start, copy_pos, bytes_remaining); +                        return 0; +                } +                else +                        memcpy(ptr_start, copy_pos, space_in_buf); +                bytes_remaining -= space_in_buf; +        } + +        return 0; +} + +du_buff_t * du_buff_create(size_t size) +{ +        du_buff_t * dub = (du_buff_t *)malloc(sizeof(du_buff_t)); + +        if (dub == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return NULL; +        } + +        dub->buffer = buffer_create(size); +        if (dub->buffer == NULL) { +                free (dub); +                return NULL; +        } + +        dub->size     = size; +        dub->du_start = 0; +        dub->du_end   = 0; + +        INIT_LIST_HEAD(&(dub->list)); + +        return dub; +} + +void du_buff_destroy(du_buff_t * dub) +{ +        if (dub == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return; +        } +        buffer_destroy_list(dub->buffer); + +        list_del(&(dub->list)); + +        free (dub); +} + +int du_buff_init(du_buff_t * dub, +                 size_t      start, +                 uint8_t *   data, +                 size_t      len) +{ +        if (dub == NULL || data == NULL) { +                LOG_DBG("Bogus input, bugging out."); +                return -EINVAL; +        } + +        if (start + len > dub->size) { +                LOG_DBGF("Index out of bounds %d", start); +                return -EINVAL; +        } + +        dub->du_start = start; +        dub->du_end = start + len; + +        return buffer_copy_data(dub->buffer, start, data, len); + +} + +uint8_t * du_buff_data_ptr_start(du_buff_t * dub) +{ +        if (dub == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return NULL; +        } +        return buffer_seek_pos(dub->buffer, dub->du_start); +} + +uint8_t * du_buff_data_ptr_end(du_buff_t * dub) +{ +        if (dub == NULL) { +                LOG_DBG("Bogus input, bugging out."); +                return NULL; +        } +        return buffer_seek_pos(dub->buffer, dub->du_end); +} + +int du_buff_head_alloc(du_buff_t * dub, size_t size) +{ +        if (dub == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return -EINVAL; +        } + +        if (dub->du_start - size < 0) { +                LOG_WARN("Failed to allocate PCI headspace"); +                return -1; +        } + +        dub->du_start -= size; + +        return 0; +} +int du_buff_tail_alloc(du_buff_t * dub, size_t size) +{ +        if (dub == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return -EINVAL; +        } + +        if (dub->du_end + size >= dub->size) { +                LOG_WARN("Failed to allocate PCI tailspace"); +                return -1; +        } + +        dub->du_end += size; + +        return 0; + +} + +int du_buff_head_release(du_buff_t * dub, size_t size) +{ +        if (dub == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return -EINVAL; +        } + +        if (size > dub->du_end - dub->du_start) { +                LOG_WARN("Tried to release beyond sdu boundary"); +                return -1; +        } + +        dub->du_start += size; + +        /* FIXME: copy some random crap to the buffer for security */ + +        return 0; +} + +int du_buff_tail_release(du_buff_t * dub, size_t size) +{ +        if (dub == NULL) { +                LOG_DBGF("Bogus input, bugging out."); +                return -EINVAL; +        } + +        if (size > dub->du_end - dub->du_start) { +                LOG_WARN("Tried to release beyond sdu boundary"); +                return -1; +        } + +        dub->du_end -= size; + +        /* FIXME: copy some random crap to the buffer for security */ + +        return 0; +} | 
