diff mbox series

[libnetfilter_queue,1/1] src: add nfq_socket_sendto() - send config request and check response

Message ID 20231211005635.7566-2-duncan_roe@optusnet.com.au
State New
Headers show
Series src: add nfq_socket_sendto() - send config request and check response | expand

Commit Message

Duncan Roe Dec. 11, 2023, 12:56 a.m. UTC
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(-)
diff mbox series

Patch

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;
+}
 
 /**
  * @}