xref: /freebsd/lib/libcasper/services/cap_netdb/cap_netdb.c (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
194dc5715SRyan Moeller /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
394dc5715SRyan Moeller  *
494dc5715SRyan Moeller  * Copyright (c) 2020 Ryan Moeller <freqlabs@FreeBSD.org>
594dc5715SRyan Moeller  *
694dc5715SRyan Moeller  * Redistribution and use in source and binary forms, with or without
794dc5715SRyan Moeller  * modification, are permitted provided that the following conditions
894dc5715SRyan Moeller  * are met:
994dc5715SRyan Moeller  * 1. Redistributions of source code must retain the above copyright
1094dc5715SRyan Moeller  *    notice, this list of conditions and the following disclaimer.
1194dc5715SRyan Moeller  * 2. Redistributions in binary form must reproduce the above copyright
1294dc5715SRyan Moeller  *    notice, this list of conditions and the following disclaimer in the
1394dc5715SRyan Moeller  *    documentation and/or other materials provided with the distribution.
1494dc5715SRyan Moeller  *
1594dc5715SRyan Moeller  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
1694dc5715SRyan Moeller  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1794dc5715SRyan Moeller  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1894dc5715SRyan Moeller  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
1994dc5715SRyan Moeller  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2094dc5715SRyan Moeller  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2194dc5715SRyan Moeller  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2294dc5715SRyan Moeller  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2394dc5715SRyan Moeller  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2494dc5715SRyan Moeller  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2594dc5715SRyan Moeller  * SUCH DAMAGE.
2694dc5715SRyan Moeller  */
2794dc5715SRyan Moeller 
2894dc5715SRyan Moeller #include <sys/cdefs.h>
2994dc5715SRyan Moeller #include <sys/dnv.h>
3094dc5715SRyan Moeller #include <sys/nv.h>
3194dc5715SRyan Moeller #include <netinet/in.h>
3294dc5715SRyan Moeller 
3394dc5715SRyan Moeller #include <assert.h>
3494dc5715SRyan Moeller #include <errno.h>
3594dc5715SRyan Moeller #include <netdb.h>
3694dc5715SRyan Moeller #include <stdlib.h>
3794dc5715SRyan Moeller #include <string.h>
3894dc5715SRyan Moeller #include <unistd.h>
3994dc5715SRyan Moeller 
4094dc5715SRyan Moeller #include <libcasper.h>
4194dc5715SRyan Moeller #include <libcasper_service.h>
4294dc5715SRyan Moeller 
4394dc5715SRyan Moeller #include "cap_netdb.h"
4494dc5715SRyan Moeller 
4594dc5715SRyan Moeller static struct protoent *
protoent_unpack(nvlist_t * nvl)4694dc5715SRyan Moeller protoent_unpack(nvlist_t *nvl)
4794dc5715SRyan Moeller {
4894dc5715SRyan Moeller 	struct protoent *pp;
4994dc5715SRyan Moeller 	char **aliases;
5094dc5715SRyan Moeller 	size_t n;
5194dc5715SRyan Moeller 
5294dc5715SRyan Moeller 	pp = malloc(sizeof(*pp));
5394dc5715SRyan Moeller 	if (pp == NULL) {
5494dc5715SRyan Moeller 		nvlist_destroy(nvl);
5594dc5715SRyan Moeller 		return (NULL);
5694dc5715SRyan Moeller 	}
5794dc5715SRyan Moeller 
5894dc5715SRyan Moeller 	pp->p_name = nvlist_take_string(nvl, "name");
5994dc5715SRyan Moeller 
6094dc5715SRyan Moeller 	aliases = nvlist_take_string_array(nvl, "aliases", &n);
6194dc5715SRyan Moeller 	pp->p_aliases = realloc(aliases, sizeof(char *) * (n + 1));
6294dc5715SRyan Moeller 	if (pp->p_aliases == NULL) {
6394dc5715SRyan Moeller 		while (n-- > 0)
6494dc5715SRyan Moeller 			free(aliases[n]);
6594dc5715SRyan Moeller 		free(aliases);
6694dc5715SRyan Moeller 		free(pp->p_name);
6794dc5715SRyan Moeller 		free(pp);
6894dc5715SRyan Moeller 		nvlist_destroy(nvl);
6994dc5715SRyan Moeller 		return (NULL);
7094dc5715SRyan Moeller 	}
7194dc5715SRyan Moeller 	pp->p_aliases[n] = NULL;
7294dc5715SRyan Moeller 
7394dc5715SRyan Moeller 	pp->p_proto = (int)nvlist_take_number(nvl, "proto");
7494dc5715SRyan Moeller 
7594dc5715SRyan Moeller 	nvlist_destroy(nvl);
7694dc5715SRyan Moeller 	return (pp);
7794dc5715SRyan Moeller }
7894dc5715SRyan Moeller 
7994dc5715SRyan Moeller struct protoent *
cap_getprotobyname(cap_channel_t * chan,const char * name)8094dc5715SRyan Moeller cap_getprotobyname(cap_channel_t *chan, const char *name)
8194dc5715SRyan Moeller {
8294dc5715SRyan Moeller 	nvlist_t *nvl;
8394dc5715SRyan Moeller 
8494dc5715SRyan Moeller 	nvl = nvlist_create(0);
8594dc5715SRyan Moeller 	nvlist_add_string(nvl, "cmd", "getprotobyname");
8694dc5715SRyan Moeller 	nvlist_add_string(nvl, "name", name);
8794dc5715SRyan Moeller 	nvl = cap_xfer_nvlist(chan, nvl);
8894dc5715SRyan Moeller 	if (nvl == NULL)
8994dc5715SRyan Moeller 		return (NULL);
9094dc5715SRyan Moeller 	if (dnvlist_get_number(nvl, "error", 0) != 0) {
9194dc5715SRyan Moeller 		nvlist_destroy(nvl);
9294dc5715SRyan Moeller 		return (NULL);
9394dc5715SRyan Moeller 	}
9494dc5715SRyan Moeller 	return (protoent_unpack(nvl));
9594dc5715SRyan Moeller }
9694dc5715SRyan Moeller 
9794dc5715SRyan Moeller static void
protoent_pack(const struct protoent * pp,nvlist_t * nvl)9894dc5715SRyan Moeller protoent_pack(const struct protoent *pp, nvlist_t *nvl)
9994dc5715SRyan Moeller {
10094dc5715SRyan Moeller 	int n = 0;
10194dc5715SRyan Moeller 
10294dc5715SRyan Moeller 	nvlist_add_string(nvl, "name", pp->p_name);
10394dc5715SRyan Moeller 
10494dc5715SRyan Moeller 	while (pp->p_aliases[n] != NULL)
10594dc5715SRyan Moeller 		++n;
10694dc5715SRyan Moeller 	nvlist_add_string_array(nvl, "aliases",
10794dc5715SRyan Moeller 	    (const char * const *)pp->p_aliases, n);
10894dc5715SRyan Moeller 
10994dc5715SRyan Moeller 	nvlist_add_number(nvl, "proto", (uint64_t)pp->p_proto);
11094dc5715SRyan Moeller }
11194dc5715SRyan Moeller 
11294dc5715SRyan Moeller static int
netdb_getprotobyname(const nvlist_t * limits __unused,const nvlist_t * nvlin,nvlist_t * nvlout)11394dc5715SRyan Moeller netdb_getprotobyname(const nvlist_t *limits __unused, const nvlist_t *nvlin,
11494dc5715SRyan Moeller     nvlist_t *nvlout)
11594dc5715SRyan Moeller {
11694dc5715SRyan Moeller 	const char *name;
11794dc5715SRyan Moeller 	struct protoent *pp;
11894dc5715SRyan Moeller 
11994dc5715SRyan Moeller 	name = dnvlist_get_string(nvlin, "name", NULL);
12094dc5715SRyan Moeller 	if (name == NULL)
12194dc5715SRyan Moeller 		return (EDOOFUS);
12294dc5715SRyan Moeller 
12394dc5715SRyan Moeller 	pp = getprotobyname(name);
12494dc5715SRyan Moeller 	if (pp == NULL)
12594dc5715SRyan Moeller 		return (EINVAL);
12694dc5715SRyan Moeller 
12794dc5715SRyan Moeller 	protoent_pack(pp, nvlout);
12894dc5715SRyan Moeller 	return (0);
12994dc5715SRyan Moeller }
13094dc5715SRyan Moeller 
13194dc5715SRyan Moeller static int
netdb_limit(const nvlist_t * oldlimits __unused,const nvlist_t * newlimits __unused)13294dc5715SRyan Moeller netdb_limit(const nvlist_t *oldlimits __unused,
13394dc5715SRyan Moeller     const nvlist_t *newlimits __unused)
13494dc5715SRyan Moeller {
13594dc5715SRyan Moeller 
13694dc5715SRyan Moeller 	return (0);
13794dc5715SRyan Moeller }
13894dc5715SRyan Moeller 
13994dc5715SRyan Moeller static int
netdb_command(const char * cmd,const nvlist_t * limits,nvlist_t * nvlin,nvlist_t * nvlout)14094dc5715SRyan Moeller netdb_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
14194dc5715SRyan Moeller     nvlist_t *nvlout)
14294dc5715SRyan Moeller {
14394dc5715SRyan Moeller 	int error;
14494dc5715SRyan Moeller 
14594dc5715SRyan Moeller 	if (strcmp(cmd, "getprotobyname") == 0)
14694dc5715SRyan Moeller 		error = netdb_getprotobyname(limits, nvlin, nvlout);
14794dc5715SRyan Moeller 	else
14894dc5715SRyan Moeller 		error = NO_RECOVERY;
14994dc5715SRyan Moeller 
15094dc5715SRyan Moeller 	return (error);
15194dc5715SRyan Moeller }
15294dc5715SRyan Moeller 
15394dc5715SRyan Moeller CREATE_SERVICE("system.netdb", netdb_limit, netdb_command, 0);
154