From 91d2c947b473b3540be5474c7128a5fa4ce60934 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 20 Aug 2023 23:22:32 +0200 Subject: src: add alternative API to set up packet buffer pktb_setup_raw() is a new function to initialise a new struct pkt_buff. It takes the memory area to be used to store pkt_buff structure and the data. Data is attached to the packet buffer (not copied), ie. the packet buffer data points to the provided data pointer. pktb_head_size() is a new function to return the amount of memory to reserve for a new struct pkt_buff. Extend documentation pon pktb_alloc(). Mostly original patch from Duncan Roe . Signed-off-by: Pablo Neira Ayuso --- include/libnetfilter_queue/pktbuff.h | 3 ++ src/extra/pktbuff.c | 63 +++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/include/libnetfilter_queue/pktbuff.h b/include/libnetfilter_queue/pktbuff.h index 42bc153..a4cc2a1 100644 --- a/include/libnetfilter_queue/pktbuff.h +++ b/include/libnetfilter_queue/pktbuff.h @@ -6,6 +6,9 @@ struct pkt_buff; struct pkt_buff *pktb_alloc(int family, void *data, size_t len, size_t extra); void pktb_free(struct pkt_buff *pktb); +struct pkt_buff *pktb_setup_raw(void *pktb, int family, void *data, size_t len, size_t extra); +size_t pktb_head_size(void); + uint8_t *pktb_data(struct pkt_buff *pktb); uint32_t pktb_len(struct pkt_buff *pktb); diff --git a/src/extra/pktbuff.c b/src/extra/pktbuff.c index 005172c..40d2250 100644 --- a/src/extra/pktbuff.c +++ b/src/extra/pktbuff.c @@ -67,6 +67,14 @@ static int __pktb_setup(int family, struct pkt_buff *pktb) return 0; } +static void pktb_setup_metadata(struct pkt_buff *pktb, void *pkt_data, + size_t len, size_t extra) +{ + pktb->len = len; + pktb->data_len = len + extra; + pktb->data = pkt_data; +} + /** * pktb_alloc - allocate a new packet buffer * \param family Indicate what family. Currently supported families are @@ -76,7 +84,12 @@ static int __pktb_setup(int family, struct pkt_buff *pktb) * \param extra Extra memory in the tail to be allocated (for mangling) * * This function returns a packet buffer that contains the packet data and - * some extra memory room in the tail (if requested). + * some extra memory room in the tail (if requested). This function copies + * the memory area provided as a pointer to packet data into the packet buffer + * structure. + * + * The extra length provides extra packet data room at the tail of the packet + * buffer in case you need to mangle it. * * \return Pointer to a new userspace packet buffer or NULL on failure. * \par Errors @@ -100,10 +113,7 @@ struct pkt_buff *pktb_alloc(int family, void *data, size_t len, size_t extra) pkt_data = (uint8_t *)pktb + sizeof(struct pkt_buff); memcpy(pkt_data, data, len); - pktb->len = len; - pktb->data_len = len + extra; - - pktb->data = pkt_data; + pktb_setup_metadata(pktb, pkt_data, len, extra); if (__pktb_setup(family, pktb) < 0) { free(pktb); @@ -113,6 +123,37 @@ struct pkt_buff *pktb_alloc(int family, void *data, size_t len, size_t extra) return pktb; } +/** + * pktb_setup_raw - set up a packet buffer from memory area + * \param pktb Pointer to memory of length pktb_head_size() bytes + * \param family Supported families are AF_BRIDGE, AF_INET & AF_INET6. + * \param data Pointer to packet data + * \param len Packet data length + * \param extra Extra memory available after packet data (for mangling). + * + * Use this function to set up a packet buffer from a memory area, minimum size + * of such memory area must be pktb_head_size(). This function attaches the + * packet data that is provided to the packet buffer (data is not copied). Use + * this function as an alternative to the pktb_alloc() interface for more + * control on memory management. + * + * \return Pointer to a new userspace packet buffer or NULL on failure. + * \par Errors + * __EPROTONOSUPPORT__ _family_ was __AF_BRIDGE__ and this is not an IP packet + * (v4 or v6) + */ +EXPORT_SYMBOL +struct pkt_buff *pktb_setup_raw(void *pktb, int family, void *data, + size_t len, size_t extra) +{ + memset(pktb, 0, sizeof (struct pkt_buff)); + pktb_setup_metadata(pktb, data, len, extra); + if (__pktb_setup(family, pktb) < 0) + pktb = NULL; + + return pktb; +} + /** * pktb_data - get pointer to network packet * \param pktb Pointer to userspace packet buffer @@ -397,6 +438,18 @@ bool pktb_mangled(const struct pkt_buff *pktb) return pktb->mangled; } +/** + * pktb_head_size - get number of bytes needed for a packet buffer + * (control part only) + * \return size of struct pkt_buff + */ + +EXPORT_SYMBOL +size_t pktb_head_size(void) +{ + return sizeof(struct pkt_buff); +} + /** * @} */ -- cgit v1.2.3