summaryrefslogtreecommitdiffstats
path: root/src/nftutils.c
blob: ca178aa0fb94dc950a485dab49d4493bf17a7f03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <nft.h>

#include "nftutils.h"

#include <netdb.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;
}