summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-08-18 10:38:40 (GMT)
committerThomas Haller <thaller@redhat.com>2023-08-18 11:04:17 (GMT)
commit40578a6299adde3c55e46423e8dbb0e8448c76ad (patch)
tree4626c6e153a9d9e1b6ea6e563f97b32f0bb2251c /lib
parent8ee8b05ff59999fd88b8a6faae40e7777ccf8c98 (diff)
downloadlibnl-40578a6299adde3c55e46423e8dbb0e8448c76ad.zip
libnl-40578a6299adde3c55e46423e8dbb0e8448c76ad.tar.gz
libnl-40578a6299adde3c55e46423e8dbb0e8448c76ad.tar.bz2
lib: use getprotobyname_r(), getprotobynumber_r() if available
Avoid non-threadsafe libc API.
Diffstat (limited to 'lib')
-rw-r--r--lib/utils.c67
1 files changed, 59 insertions, 8 deletions
diff --git a/lib/utils.c b/lib/utils.c
index 04bbe81..5281c41 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -128,6 +128,57 @@ struct trans_list {
struct nl_list_head list;
};
+int nl_getprotobyname(const char *name)
+{
+ const struct protoent *result;
+
+#if HAVE_DECL_GETPROTOBYNAME_R
+ struct protoent result_buf;
+ char buf[2048];
+ 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 nl_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[2048];
+ 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;
+}
+
const char *nl_strerror_l(int err)
{
const char *buf;
@@ -870,12 +921,8 @@ int nl_str2ether_proto(const char *name)
char *nl_ip_proto2str(int proto, char *buf, size_t len)
{
- struct protoent *p = getprotobynumber(proto);
-
- if (p) {
- snprintf(buf, len, "%s", p->p_name);
+ if (nl_getprotobynumber(proto, buf, len))
return buf;
- }
snprintf(buf, len, "0x%x", proto);
return buf;
@@ -883,12 +930,16 @@ char *nl_ip_proto2str(int proto, char *buf, size_t len)
int nl_str2ip_proto(const char *name)
{
- struct protoent *p = getprotobyname(name);
unsigned long l;
char *end;
+ int p;
+
+ if (!name)
+ return -NLE_INVAL;
- if (p)
- return p->p_proto;
+ p = nl_getprotobyname(name);
+ if (p >= 0)
+ return p;
l = strtoul(name, &end, 0);
if (name == end || *end != '\0' || l > (unsigned long)INT_MAX)