summaryrefslogtreecommitdiffstats
path: root/src/nftutils.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-08-18 16:08:19 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2023-08-20 23:48:26 +0200
commit7076523e482110d59c4456f4a795581a2ca39c41 (patch)
tree9b1cf7707f110fd3402dae19419b17722f66dfd2 /src/nftutils.c
parent4646d656466b1f05bd765bbfb4d6d7bf1529bdbd (diff)
nftutils: add and use wrappers for getprotoby{name,number}_r(), getservbyport_r()
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. These wrappers are thread-safe, if libc provides the reentrant versions. Use them. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/nftutils.c')
-rw-r--r--src/nftutils.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/nftutils.c b/src/nftutils.c
new file mode 100644
index 00000000..13f879dd
--- /dev/null
+++ b/src/nftutils.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#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;
+}