mirror of
https://github.com/systemd/systemd.git
synced 2025-03-14 04:58:28 +03:00
test-nss: allow the module and names/addresses to be specified (#4258)
Useful for testing a single module. If nothing is specified, behaviour is the same as before. $ ./test-nss myhostname 192.168.0.14 localhost ======== myhostname ======== _nss_myhostname_gethostbyname4_r("localhost") → status=NSS_STATUS_SUCCESS pat=buffer+0x38 errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "localhost" AF_INET 127.0.0.1 %lo "localhost" AF_INET6 ::1 %lo _nss_myhostname_gethostbyname3_r("localhost", AF_INET) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "localhost" AF_INET 127.0.0.1 canonical: "localhost" _nss_myhostname_gethostbyname3_r("localhost", AF_INET6) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "localhost" AF_INET6 ::1 canonical: "localhost" _nss_myhostname_gethostbyname3_r("localhost", *) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "localhost" AF_INET 127.0.0.1 canonical: "localhost" _nss_myhostname_gethostbyname3_r("localhost", AF_UNIX) → status=NSS_STATUS_UNAVAIL errno=97/EAFNOSUPPORT h_errno=4/No address associated with name ttl=2147483647 _nss_myhostname_gethostbyname2_r("localhost", AF_INET) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "localhost" AF_INET 127.0.0.1 _nss_myhostname_gethostbyname2_r("localhost", AF_INET6) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "localhost" AF_INET6 ::1 _nss_myhostname_gethostbyname2_r("localhost", *) → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "localhost" AF_INET 127.0.0.1 _nss_myhostname_gethostbyname2_r("localhost", AF_UNIX) → status=NSS_STATUS_UNAVAIL errno=97/EAFNOSUPPORT h_errno=4/No address associated with name _nss_myhostname_gethostbyname_r("localhost") → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "localhost" AF_INET 127.0.0.1 _nss_myhostname_gethostbyaddr2_r("192.168.0.14") → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "laptop" AF_INET 192.168.0.14 AF_INET 192.168.122.1 AF_INET 169.254.209.76 _nss_myhostname_gethostbyaddr_r("192.168.0.14") → status=NSS_STATUS_SUCCESS errno=0/--- h_errno=0/Resolver Error 0 (no error) "laptop" AF_INET 192.168.0.14 AF_INET 192.168.122.1 AF_INET 169.254.209.76
This commit is contained in:
parent
d48bb46b5a
commit
9f7672b3bc
@ -77,7 +77,8 @@ static void* open_handle(const char* dir, const char* module, int flags) {
|
||||
path = strjoina("libnss_", module, ".so.2");
|
||||
|
||||
handle = dlopen(path, flags);
|
||||
assert_se(handle);
|
||||
if (!handle)
|
||||
log_error("Failed to load module %s: %s", module, dlerror());
|
||||
return handle;
|
||||
}
|
||||
|
||||
@ -379,75 +380,158 @@ static void test_byaddr(void *handle,
|
||||
puts("");
|
||||
}
|
||||
|
||||
static int make_addresses(struct local_address **addresses) {
|
||||
int n;
|
||||
size_t n_alloc;
|
||||
_cleanup_free_ struct local_address *addrs = NULL;
|
||||
|
||||
n = local_addresses(NULL, 0, AF_UNSPEC, &addrs);
|
||||
if (n < 0)
|
||||
log_info_errno(n, "Failed to query local addresses: %m");
|
||||
|
||||
n_alloc = n; /* we _can_ do that */
|
||||
if (!GREEDY_REALLOC(addrs, n_alloc, n + 3))
|
||||
return log_oom();
|
||||
|
||||
addrs[n++] = (struct local_address) { .family = AF_INET,
|
||||
.address.in = { htobe32(0x7F000001) } };
|
||||
addrs[n++] = (struct local_address) { .family = AF_INET,
|
||||
.address.in = { htobe32(0x7F000002) } };
|
||||
addrs[n++] = (struct local_address) { .family = AF_INET6,
|
||||
.address.in6 = in6addr_loopback };
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_one_module(const char* dir,
|
||||
const char *module,
|
||||
char **names,
|
||||
struct local_address *addresses,
|
||||
int n_addresses) {
|
||||
void *handle;
|
||||
char **name;
|
||||
int i;
|
||||
|
||||
|
||||
log_info("======== %s ========", module);
|
||||
|
||||
handle = open_handle(streq(module, "dns") ? NULL : dir,
|
||||
module,
|
||||
RTLD_LAZY|RTLD_NODELETE);
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
STRV_FOREACH(name, names)
|
||||
test_byname(handle, module, *name);
|
||||
|
||||
for (i = 0; i < n_addresses; i++)
|
||||
test_byaddr(handle, module,
|
||||
&addresses[i].address,
|
||||
FAMILY_ADDRESS_SIZE(addresses[i].family),
|
||||
addresses[i].family);
|
||||
|
||||
log_info(" ");
|
||||
dlclose(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char **argv,
|
||||
char ***the_modules,
|
||||
char ***the_names,
|
||||
struct local_address **the_addresses, int *n_addresses) {
|
||||
|
||||
int r, n = 0;
|
||||
_cleanup_strv_free_ char **modules = NULL, **names = NULL;
|
||||
_cleanup_free_ struct local_address *addrs = NULL;
|
||||
size_t n_allocated = 0;
|
||||
|
||||
if (argc > 1)
|
||||
modules = strv_new(argv[1], NULL);
|
||||
else
|
||||
modules = strv_new(
|
||||
#ifdef HAVE_MYHOSTNAME
|
||||
# define MODULE1 "myhostname\0"
|
||||
#else
|
||||
# define MODULE1
|
||||
"myhostname",
|
||||
#endif
|
||||
#ifdef HAVE_RESOLVED
|
||||
# define MODULE2 "resolve\0"
|
||||
#else
|
||||
# define MODULE2
|
||||
"resolve",
|
||||
#endif
|
||||
#ifdef HAVE_MACHINED
|
||||
# define MODULE3 "mymachines\0"
|
||||
#else
|
||||
# define MODULE3
|
||||
"mymachines",
|
||||
#endif
|
||||
#define MODULE4 "dns\0"
|
||||
"dns",
|
||||
NULL);
|
||||
if (!modules)
|
||||
return -ENOMEM;
|
||||
|
||||
if (argc > 2) {
|
||||
char **name;
|
||||
int family;
|
||||
union in_addr_union address;
|
||||
|
||||
STRV_FOREACH(name, argv + 2) {
|
||||
r = in_addr_from_string_auto(*name, &family, &address);
|
||||
if (r < 0) {
|
||||
/* assume this is a name */
|
||||
r = strv_extend(&names, *name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
if (!GREEDY_REALLOC0(addrs, n_allocated, n + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
addrs[n++] = (struct local_address) { .family = family,
|
||||
.address = address };
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_cleanup_free_ char *hostname;
|
||||
|
||||
hostname = gethostname_malloc();
|
||||
if (!hostname)
|
||||
return -ENOMEM;
|
||||
|
||||
names = strv_new("localhost", "gateway", "foo_no_such_host", hostname, NULL);
|
||||
if (!names)
|
||||
return -ENOMEM;
|
||||
|
||||
n = make_addresses(&addrs);
|
||||
if (n < 0)
|
||||
return n;
|
||||
}
|
||||
|
||||
*the_modules = modules;
|
||||
*the_names = names;
|
||||
modules = names = NULL;
|
||||
*the_addresses = addrs;
|
||||
*n_addresses = n;
|
||||
addrs = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
_cleanup_free_ char *dir = NULL, *hostname = NULL;
|
||||
const char *module;
|
||||
|
||||
const uint32_t local_address_ipv4 = htobe32(0x7F000001);
|
||||
const uint32_t local_address_ipv4_2 = htobe32(0x7F000002);
|
||||
_cleanup_free_ char *dir = NULL;
|
||||
_cleanup_strv_free_ char **modules = NULL, **names = NULL;
|
||||
_cleanup_free_ struct local_address *addresses = NULL;
|
||||
int n_addresses;
|
||||
char **module;
|
||||
int r;
|
||||
|
||||
log_set_max_level(LOG_INFO);
|
||||
log_parse_environment();
|
||||
|
||||
dir = dirname_malloc(argv[0]);
|
||||
assert_se(dir);
|
||||
|
||||
hostname = gethostname_malloc();
|
||||
assert_se(hostname);
|
||||
|
||||
n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
|
||||
if (n_addresses < 0) {
|
||||
log_info_errno(n_addresses, "Failed to query local addresses: %m");
|
||||
n_addresses = 0;
|
||||
r = parse_argv(argc, argv, &modules, &names, &addresses, &n_addresses);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to parse arguments: %m");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
NULSTR_FOREACH(module, MODULE1 MODULE2 MODULE3 MODULE4) {
|
||||
void *handle;
|
||||
const char *name;
|
||||
int i;
|
||||
dir = dirname_malloc(argv[0]);
|
||||
if (!dir)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
log_info("======== %s ========", module);
|
||||
|
||||
handle = open_handle(streq(module, "dns") ? NULL : dir,
|
||||
module,
|
||||
RTLD_LAZY|RTLD_NODELETE);
|
||||
NULSTR_FOREACH(name, "localhost\0" "gateway\0" "foo_no_such_host\0")
|
||||
test_byname(handle, module, name);
|
||||
|
||||
test_byname(handle, module, hostname);
|
||||
|
||||
test_byaddr(handle, module, &local_address_ipv4, sizeof local_address_ipv4, AF_INET);
|
||||
test_byaddr(handle, module, &local_address_ipv4_2, sizeof local_address_ipv4_2, AF_INET);
|
||||
test_byaddr(handle, module, &in6addr_loopback, sizeof in6addr_loopback, AF_INET6);
|
||||
|
||||
for (i = 0; i < n_addresses; i++)
|
||||
test_byaddr(handle, module,
|
||||
&addresses[i].address,
|
||||
FAMILY_ADDRESS_SIZE(addresses[i].family),
|
||||
addresses[i].family);
|
||||
|
||||
dlclose(handle);
|
||||
|
||||
log_info(" ");
|
||||
STRV_FOREACH(module, modules) {
|
||||
r = test_one_module(dir, *module, names, addresses, n_addresses);
|
||||
if (r < 0)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
Loading…
x
Reference in New Issue
Block a user