@@ -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" */
@@ -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;
+}
/**
* @}
Classic convenience function to complement nfq_nlmsg_put2(). Signed-off-by: Duncan Roe <duncan_roe@optusnet.com.au> --- .../libnetfilter_queue/libnetfilter_queue.h | 2 + src/nlmsg.c | 54 +++++++++++++------ 2 files changed, 41 insertions(+), 15 deletions(-)