diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2023-08-20 23:22:32 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2023-08-20 23:30:36 +0200 |
commit | 91d2c947b473b3540be5474c7128a5fa4ce60934 (patch) | |
tree | 057fae93bb52b981e611dad7fd018bb578a702da /src | |
parent | 8020c6705834cf62e9536d6bc278e3daa9bd8160 (diff) |
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 <duncan_roe@optusnet.com.au>.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/extra/pktbuff.c | 63 |
1 files changed, 58 insertions, 5 deletions
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); @@ -114,6 +124,37 @@ struct pkt_buff *pktb_alloc(int family, void *data, size_t len, size_t extra) } /** + * 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 * \return Pointer to start of network packet data within __pktb__ @@ -398,5 +439,17 @@ bool pktb_mangled(const struct pkt_buff *pktb) } /** + * 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); +} + +/** * @} */ |