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