diff options
Diffstat (limited to 'pkt_buff.h')
-rw-r--r-- | pkt_buff.h | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/pkt_buff.h b/pkt_buff.h new file mode 100644 index 0000000..f86c011 --- /dev/null +++ b/pkt_buff.h @@ -0,0 +1,112 @@ +/* + * netsniff-ng - the packet sniffing beast + * Copyright (C) 2012 Christoph Jaeger <christoph@netsniff-ng.org> + * Subject to the GPL, version 2. + */ + +#ifndef PKT_BUFF_H +#define PKT_BUFF_H + +#include "hash.h" +#include "built_in.h" +#include "proto.h" +#include "xmalloc.h" + +struct pkt_buff { + /* invariant: head <= data <= tail */ + uint8_t *head; + uint8_t *data; + uint8_t *tail; + unsigned int size; + + struct protocol *proto; +}; + +static inline struct pkt_buff *pkt_alloc(uint8_t *packet, unsigned int len) +{ + struct pkt_buff *pkt = xmalloc(sizeof(*pkt)); + + pkt->head = packet; + pkt->data = packet; + pkt->tail = packet + len; + pkt->size = len; + pkt->proto = NULL; + + return pkt; +} + +static inline void pkt_free(struct pkt_buff *pkt) +{ + xfree(pkt); +} + +static inline unsigned int pkt_len(struct pkt_buff *pkt) +{ + bug_on(!pkt || pkt->data > pkt->tail); + + return pkt->tail - pkt->data; +} + +static inline uint8_t *pkt_pull(struct pkt_buff *pkt, unsigned int len) +{ + uint8_t *data = NULL; + + bug_on(!pkt || pkt->head > pkt->data || pkt->data > pkt->tail); + + if (len <= pkt_len(pkt)) { + data = pkt->data; + pkt->data += len; + } + + bug_on(!pkt || pkt->head > pkt->data || pkt->data > pkt->tail); + + return data; +} + +static inline uint8_t *pkt_peek(struct pkt_buff *pkt) +{ + bug_on(!pkt || pkt->head > pkt->data || pkt->data > pkt->tail); + + return pkt->data; +} + +static inline unsigned int pkt_trim(struct pkt_buff *pkt, unsigned int len) +{ + unsigned int ret = 0; + + bug_on(!pkt || pkt->head > pkt->data || pkt->data > pkt->tail); + + if (len <= pkt_len(pkt)) + ret = len; + + pkt->tail -= ret; + bug_on(!pkt || pkt->head > pkt->data || pkt->data > pkt->tail); + + return ret; +} + +static inline uint8_t *pkt_pull_tail(struct pkt_buff *pkt, unsigned int len) +{ + uint8_t *tail = NULL; + + bug_on(!pkt || pkt->head > pkt->data || pkt->data > pkt->tail); + + if (len <= pkt_len(pkt)) { + tail = pkt->tail; + pkt->tail -= len; + } + + return tail; +} + +static inline void pkt_set_proto(struct pkt_buff *pkt, struct hash_table *table, + unsigned int key) +{ + bug_on(!pkt || !table); + + pkt->proto = (struct protocol *) lookup_hash(key, table); + while (pkt->proto && key != pkt->proto->key) + pkt->proto = pkt->proto->next; +} + +#endif /* PKT_BUFF_H */ |