Classic convenience function to complement nfq_nlmsg_put2(). Signed-off-by: Duncan Roe <duncan_roe@xxxxxxxxxxxxxxx> --- .../libnetfilter_queue/libnetfilter_queue.h | 2 + src/nlmsg.c | 54 +++++++++++++------ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/include/libnetfilter_queue/libnetfilter_queue.h b/include/libnetfilter_queue/libnetfilter_queue.h index f7e68d8..724789a 100644 --- a/include/libnetfilter_queue/libnetfilter_queue.h +++ b/include/libnetfilter_queue/libnetfilter_queue.h @@ -15,6 +15,7 @@ #include <sys/time.h> #include <libnfnetlink/libnfnetlink.h> +#include <libmnl/libmnl.h> #include <libnetfilter_queue/linux_nfnetlink_queue.h> @@ -152,6 +153,7 @@ void nfq_nlmsg_verdict_put_pkt(struct nlmsghdr *nlh, const void *pkt, uint32_t p int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr); struct nlmsghdr *nfq_nlmsg_put(char *buf, int type, uint32_t queue_num); struct nlmsghdr *nfq_nlmsg_put2(char *buf, int type, uint32_t queue_num, uint16_t flags); +int nfq_socket_sendto(struct mnl_socket *nl, struct nlmsghdr *nlh, char *buf, unsigned int portid); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/nlmsg.c b/src/nlmsg.c index 39fd12d..d605da8 100644 --- a/src/nlmsg.c +++ b/src/nlmsg.c @@ -336,29 +336,16 @@ struct nlmsghdr *nfq_nlmsg_put(char *buf, int type, uint32_t queue_num) * \n * This code snippet demonstrates reading these responses: * \verbatim - char buf[MNL_SOCKET_BUFFER_SIZE]; - nlh = nfq_nlmsg_put2(buf, NFQNL_MSG_CONFIG, queue_num, NLM_F_ACK); mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, NFQA_CFG_F_SECCTX); mnl_attr_put_u32(nlh, NFQA_CFG_MASK, NFQA_CFG_F_SECCTX); - if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_send"); - exit(EXIT_FAILURE); - } - - ret = mnl_socket_recvfrom(nl, buf, sizeof buf); - if (ret == -1) { - perror("mnl_socket_recvfrom"); - exit(EXIT_FAILURE); - } - - ret = mnl_cb_run(buf, ret, 0, portid, NULL, NULL); - if (ret == -1) + if (nfq_socket_sendto(nl, nlh, buf, portid == -1) fprintf(stderr, "This kernel version does not allow to " "retrieve security context.\n"); \endverbatim + * \sa __nfq_socket_sendto__(3) * */ @@ -377,6 +364,43 @@ struct nlmsghdr *nfq_nlmsg_put2(char *buf, int type, uint32_t queue_num, return nlh; } +/** + * nfq_socket_sendto - send a netlink message and read response from kernel + * \param nl Netlink socket obtained via \b mnl_socket_open() + * \param nlh Pointer to Netlink message to be sent + * \param buf Pointer to memory buffer of at least MNL_SOCKET_BUFFER_SIZE bytes + * \param portid Netlink PortID that we expect to receive + * \note \b nlh and \b buf may refer to the same memory location. + * + * Use nfq_socket_sendto() instead of \b mnl_socket_sendto() after + * nfq_nlmsg_put2() has set the NLM_F_ACK flag in *<b>nlh</b>. + * + * \return 0 or -1 on failure with \b errno set + * \par Errors + * __EOPNOTSUPP__ the kernel cannot action a facility requested by an + * NFQA_CFG_F_-prefixed flag. + * If there were several such flags, none have been actioned. + * \par + * Other errors from underlying libmnl calls are possible. + * + * \sa __nfq_nlmsg_put2__(3), __mnl_socket_sendto__(3), + * __mnl_socket_recvfrom__(3), __mnl_cb_run__(3) + * + */ + +EXPORT_SYMBOL +int nfq_socket_sendto(struct mnl_socket *nl, struct nlmsghdr *nlh, char *buf, + unsigned int portid) +{ + int ret; + + ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len); + if (ret != -1) + ret = mnl_socket_recvfrom(nl, buf, MNL_SOCKET_BUFFER_SIZE); + if (ret != -1) + ret = mnl_cb_run(buf, ret, 0, portid, NULL, NULL); + return ret == -1 ? -1 : 0; +} /** * @} -- 2.35.8