From: Thomas Haller <thaller@redhat.com>
To: NetFilter <netfilter-devel@vger.kernel.org>
Cc: Thomas Haller <thaller@redhat.com>
Subject: [nft PATCH v3 2/3] nftutils: add wrappers for getprotoby{name,number}_r(), getservbyport_r()
Date: Fri, 18 Aug 2023 16:08:20 +0200 [thread overview]
Message-ID: <20230818141124.859037-3-thaller@redhat.com> (raw)
In-Reply-To: <20230818141124.859037-1-thaller@redhat.com>
We should aim to use the thread-safe variants of getprotoby{name,number}
and getservbyport(). However, they may not be available with other libc,
so it requires a configure check. As that is cumbersome, add wrappers
that do that at one place.
Signed-off-by: Thomas Haller <thaller@redhat.com>
---
configure.ac | 4 +++
src/nftutils.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/nftutils.h | 16 +++++++++
3 files changed, 117 insertions(+)
diff --git a/configure.ac b/configure.ac
index b0201ac3528e..42f0dc4cf392 100644
--- a/configure.ac
+++ b/configure.ac
@@ -108,6 +108,10 @@ AC_DEFINE([HAVE_LIBJANSSON], [1], [Define if you have libjansson])
])
AM_CONDITIONAL([BUILD_JSON], [test "x$with_json" != xno])
+AC_CHECK_DECLS([getprotobyname_r, getprotobynumber_r, getservbyport_r], [], [], [[
+#include <netdb.h>
+]])
+
AC_CONFIG_FILES([ \
Makefile \
libnftables.pc \
diff --git a/src/nftutils.c b/src/nftutils.c
index 758283d1b650..13f879ddc5c7 100644
--- a/src/nftutils.c
+++ b/src/nftutils.c
@@ -3,3 +3,100 @@
#include <config.h>
#include "nftutils.h"
+
+#include <netdb.h>
+#include <string.h>
+#include <stdint.h>
+
+/* Buffer size used for getprotobynumber_r() and similar. The manual comments
+ * that a buffer of 1024 should be sufficient "for most applications"(??), so
+ * let's double it. It still fits reasonably on the stack, so no need to
+ * choose a smaller one. */
+#define NETDB_BUFSIZE 2048
+
+bool nft_getprotobynumber(int proto, char *out_name, size_t name_len)
+{
+ const struct protoent *result;
+
+#if HAVE_DECL_GETPROTOBYNUMBER_R
+ struct protoent result_buf;
+ char buf[NETDB_BUFSIZE];
+ int r;
+
+ r = getprotobynumber_r(proto,
+ &result_buf,
+ buf,
+ sizeof(buf),
+ (struct protoent **) &result);
+ if (r != 0 || result != &result_buf)
+ result = NULL;
+#else
+ result = getprotobynumber(proto);
+#endif
+
+ if (!result)
+ return false;
+
+ if (strlen(result->p_name) >= name_len)
+ return false;
+ strcpy(out_name, result->p_name);
+ return true;
+}
+
+int nft_getprotobyname(const char *name)
+{
+ const struct protoent *result;
+
+#if HAVE_DECL_GETPROTOBYNAME_R
+ struct protoent result_buf;
+ char buf[NETDB_BUFSIZE];
+ int r;
+
+ r = getprotobyname_r(name,
+ &result_buf,
+ buf,
+ sizeof(buf),
+ (struct protoent **) &result);
+ if (r != 0 || result != &result_buf)
+ result = NULL;
+#else
+ result = getprotobyname(name);
+#endif
+
+ if (!result)
+ return -1;
+
+ if (result->p_proto < 0 || result->p_proto > UINT8_MAX)
+ return -1;
+ return (uint8_t) result->p_proto;
+}
+
+bool nft_getservbyport(int port, const char *proto, char *out_name, size_t name_len)
+{
+ const struct servent *result;
+
+#if HAVE_DECL_GETSERVBYPORT_R
+ struct servent result_buf;
+ char buf[NETDB_BUFSIZE];
+ int r;
+
+ r = getservbyport_r(port,
+ proto,
+ &result_buf,
+ buf,
+ sizeof(buf),
+ (struct servent**) &result);
+ if (r != 0 || result != &result_buf)
+ result = NULL;
+#else
+ result = getservbyport(port, proto);
+#endif
+
+ if (!result)
+ return false;
+
+ if (strlen(result->s_name) >= name_len)
+ return false;
+ strcpy(out_name, result->s_name);
+ return true;
+}
diff --git a/src/nftutils.h b/src/nftutils.h
index 9ad68d55ce47..cb584b9ca32b 100644
--- a/src/nftutils.h
+++ b/src/nftutils.h
@@ -2,4 +2,20 @@
#ifndef NFTUTILS_H
#define NFTUTILS_H
+#include <stdbool.h>
+#include <stddef.h>
+
+/* The maximum buffer size for (struct protoent).p_name. It is excessively large,
+ * while still reasonably fitting on the stack. Arbitrarily chosen. */
+#define NFT_PROTONAME_MAXSIZE 1024
+
+bool nft_getprotobynumber(int number, char *out_name, size_t name_len);
+int nft_getprotobyname(const char *name);
+
+/* The maximum buffer size for (struct servent).s_name. It is excessively large,
+ * while still reasonably fitting on the stack. Arbitrarily chosen. */
+#define NFT_SERVNAME_MAXSIZE 1024
+
+bool nft_getservbyport(int port, const char *proto, char *out_name, size_t name_len);
+
#endif /* NFTUTILS_H */
--
2.41.0
next prev parent reply other threads:[~2023-08-18 14:13 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-18 14:08 [nft PATCH v3 0/3] src: use reentrant getprotobyname_r()/getprotobynumber_r()/getservbyport_r() Thomas Haller
2023-08-18 14:08 ` [nft PATCH v3 1/3] nftutils: add new internal file for general utilities Thomas Haller
2023-08-18 14:08 ` Thomas Haller [this message]
2023-08-18 14:08 ` [nft PATCH v3 3/3] src: use wrappers for getprotoby{name,number}_r(), getservbyport_r() Thomas Haller
2023-08-18 16:12 ` [nft PATCH v3 0/3] src: use reentrant getprotobyname_r()/getprotobynumber_r()/getservbyport_r() Pablo Neira Ayuso
2023-08-18 17:39 ` Thomas Haller
2023-08-20 20:35 ` Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230818141124.859037-3-thaller@redhat.com \
--to=thaller@redhat.com \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).