Page MenuHomeFreeBSD

D26956.diff
No OneTemporary

D26956.diff

Index: lib/libcasper/services/cap_net/Makefile
===================================================================
--- lib/libcasper/services/cap_net/Makefile
+++ lib/libcasper/services/cap_net/Makefile
@@ -44,5 +44,6 @@
MLINKS+=cap_net.3 cap_gethostbyname.3
MLINKS+=cap_net.3 cap_gethostbyname2.3
MLINKS+=cap_net.3 cap_getnameinfo.3
+MLINKS+=cap_net.3 cap_getprotobyname.3
.include <bsd.lib.mk>
Index: lib/libcasper/services/cap_net/cap_net.h
===================================================================
--- lib/libcasper/services/cap_net/cap_net.h
+++ lib/libcasper/services/cap_net/cap_net.h
@@ -36,11 +36,11 @@
#include <sys/dnv.h>
#include <sys/nv.h>
-
#include <sys/socket.h>
struct addrinfo;
struct hostent;
+struct protoent;
struct cap_net_limit;
typedef struct cap_net_limit cap_net_limit_t;
@@ -66,6 +66,8 @@
socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen,
int flags);
+struct protoent *cap_getprotobyname(cap_channel_t *chan, const char *name);
+
/* Limit functions. */
cap_net_limit_t *cap_net_limit_init(cap_channel_t *chan, uint64_t mode);
int cap_net_limit(cap_net_limit_t *limit);
@@ -103,6 +105,8 @@
getaddrinfo(hostname, servname, hints, res)
#define cap_getnameinfo(chan, sa, salen, host, hostlen, serv, servlen, flags) \
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
+#define cap_getprotobyname(chan, name) \
+ getprotobyname(name)
/* Limit functions. */
#define cap_net_limit_init(chan, mode) ((cap_net_limit_t *)malloc(8))
Index: lib/libcasper/services/cap_net/cap_net.3
===================================================================
--- lib/libcasper/services/cap_net/cap_net.3
+++ lib/libcasper/services/cap_net/cap_net.3
@@ -34,6 +34,7 @@
.Nm cap_gethostbyname ,
.Nm cap_gethostbyname2 ,
.Nm cap_getnameinfo ,
+.Nm cap_getprotobyname ,
.Nm cap_net_free ,
.Nm cap_net_limit ,
.Nm cap_net_limit_addr2name ,
@@ -64,6 +65,8 @@
.Fn cap_gethostbyname2 "const cap_channel_t *chan" "const char *name" "int af"
.Ft "struct hostent *"
.Fn cap_gethostbyaddr "const cap_channel_t *chan" "const void *addr" "socklen_t len" "int af"
+.Ft "struct protoent *"
+.Fn cap_getprotobyname "const cap_channel_t *chan" "const char *name"
.Ft "cap_net_limit_t *"
.Fn cap_net_limit_init "cap_channel_t *chan" "uint64_t mode"
.Ft int
@@ -89,17 +92,19 @@
.Fn cap_connect,
.Fn cap_gethostbyname ,
.Fn cap_gethostbyname2 ,
-.Fn cap_gethostbyaddr
+.Fn cap_gethostbyaddr ,
+.Fn cap_getnameinfo ,
and
-.Fn cap_getnameinfo
+.Fn cap_getprotobyname
are respectively equivalent to
.Xr bind 2 ,
.Xr connect 2 ,
.Xr gethostbyname 3 ,
.Xr gethostbyname2 3 ,
-.Xr gethostbyaddr 3
+.Xr gethostbyaddr 3 ,
+.Xr getnameinfo 3 ,
and
-.Xr getnameinfo 3
+.Xr getprotobyname 3
except that the connection to the
.Nm system.net
service needs to be provided.
@@ -224,6 +229,7 @@
int familylimit, error, s;
const char *host = "example.com";
struct addrinfo hints, *res;
+struct protoent *ent;
/* Open capability to Casper. */
capcas = cap_init();
@@ -245,20 +251,26 @@
/* Close Casper capability. */
cap_close(capcas);
+/* Get information about TCP. */
+ent = cap_getprotobyname(capnet, "tcp");
+if (ent == NULL)
+ err(1, "Unable to get TCP info");
+
/* Limit system.net to reserve IPv4 addresses, to host example.com . */
limit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | CAPNET_CONNECTDNS);
if (limit == NULL)
- err(1, "Unable to create limits.");
+ err(1, "Unable to create limits");
cap_net_limit_name2addr(limit, host, "80");
familylimit = AF_INET;
cap_net_limit_name2addr_family(limit, &familylimit, 1);
if (cap_net_limit(limit) < 0)
- err(1, "Unable to apply limits.");
+ err(1, "Unable to apply limits");
/* Find IP addresses for the given host. */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
+hints.ai_protocol = ent->p_proto;
error = cap_getaddrinfo(capnet, host, "80", &hints, &res);
if (error != 0)
@@ -281,7 +293,9 @@
.Xr gethostbyname 3 ,
.Xr gethostbyname2 3 ,
.Xr getnameinfo 3 ,
+.Xr getprotobyname 3 ,
.Xr capsicum 4 ,
.Xr nv 9
.Sh AUTHORS
.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org
+.An Ryan Moeller Aq Mt freqlabs@FreeBSD.org
Index: lib/libcasper/services/cap_net/cap_net.c
===================================================================
--- lib/libcasper/services/cap_net/cap_net.c
+++ lib/libcasper/services/cap_net/cap_net.c
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2020 Mariusz Zaborski <oshogbo@FreeBSD.org>
+ * Copyright (c) 2020 Ryan Moeller <freqlabs@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,6 +39,7 @@
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -375,6 +377,74 @@
return (0);
}
+static void
+protoent_free(struct protoent *pp)
+{
+
+ free(pp->p_name);
+ pp->p_name = NULL;
+ if (pp->p_aliases != NULL) {
+ while (*pp->p_aliases != NULL)
+ free(*pp->p_aliases++);
+ free(pp->p_aliases);
+ }
+}
+
+static struct protoent *
+protoent_unpack(const nvlist_t *nvl, struct protoent *pp)
+{
+ const char * const *aliases = NULL;
+ size_t n;
+
+ protoent_free(pp);
+
+ pp->p_name = strdup(nvlist_get_string(nvl, "name"));
+ if (pp->p_name == NULL)
+ goto fail;
+
+ aliases = nvlist_get_string_array(nvl, "aliases", &n);
+ if (aliases == NULL)
+ goto fail;
+ pp->p_aliases = calloc(sizeof(char *), n + 1);
+ if (pp->p_aliases == NULL)
+ goto fail;
+ pp->p_aliases[n] = NULL;
+ while (n-- > 0) {
+ if ((pp->p_aliases[n] = strdup(aliases[n])) == NULL) {
+ for (++n; pp->p_aliases[n] != NULL; ++n) {
+ free(pp->p_aliases[n]);
+ pp->p_aliases[n] = NULL;
+ }
+ goto fail;
+ }
+ }
+
+ pp->p_proto = (int)nvlist_get_number(nvl, "proto");
+
+ return (pp);
+fail:
+ protoent_free(pp);
+ return (NULL);
+}
+
+struct protoent *
+cap_getprotobyname(cap_channel_t *chan, const char *name)
+{
+ struct protoent *pp, pent = { 0 };
+ nvlist_t *nvl;
+
+ nvl = nvlist_create(0);
+ nvlist_add_string(nvl, "cmd", "getprotobyname");
+ nvlist_add_string(nvl, "name", name);
+ nvl = cap_xfer_nvlist(chan, nvl);
+ if (nvl == NULL || dnvlist_get_number(nvl, "error", 0) != 0)
+ return (NULL);
+
+ pp = protoent_unpack(nvl, &pent);
+ nvlist_destroy(nvl);
+ return (pp);
+}
+
cap_net_limit_t *
cap_net_limit_init(cap_channel_t *chan, uint64_t mode)
{
@@ -1004,6 +1074,34 @@
return (error);
}
+static void
+protoent_pack(const struct protoent *pp, nvlist_t *nvl)
+{
+ int n = 0;
+
+ nvlist_add_string(nvl, "name", pp->p_name);
+
+ while (pp->p_aliases[n] != NULL)
+ ++n;
+ nvlist_add_string_array(nvl, "aliases",
+ (const char * const *)pp->p_aliases, n);
+
+ nvlist_add_number(nvl, "proto", (uint64_t)pp->p_proto);
+}
+
+static int
+net_getprotobyname(const nvlist_t *limits __unused, const nvlist_t *nvlin,
+ nvlist_t *nvlout)
+{
+ struct protoent *pp;
+
+ pp = getprotobyname(nvlist_get_string(nvlin, "name"));
+ if (pp == NULL)
+ return (ENOENT);
+ protoent_pack(pp, nvlout);
+ return (0);
+}
+
static int
net_bind(const nvlist_t *limits, nvlist_t *nvlin, nvlist_t *nvlout)
{
@@ -1378,6 +1476,8 @@
return (net_getnameinfo(limits, nvlin, nvlout));
else if (strcmp(cmd, "getaddrinfo") == 0)
return (net_getaddrinfo(limits, nvlin, nvlout));
+ else if (strcmp(cmd, "getprotobyname") == 0)
+ return (net_getprotobyname(limits, nvlin, nvlout));
return (EINVAL);
}
Index: lib/libcasper/services/cap_net/tests/net_test.c
===================================================================
--- lib/libcasper/services/cap_net/tests/net_test.c
+++ lib/libcasper/services/cap_net/tests/net_test.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2020 Mariusz Zaborski <oshogbo@FreeBSD.org>
+ * Copyright (c) 2020 Ryan Moeller <freqlabs@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1126,6 +1127,28 @@
cap_close(capnet);
}
+ATF_TC_WITHOUT_HEAD(capnet__getprotobyname);
+ATF_TC_BODY(capnet__getprotobyname, tc)
+{
+ cap_channel_t *capnet;
+ struct protoent *pp;
+ size_t n = 0;
+
+ capnet = create_network_service();
+
+ pp = cap_getprotobyname(capnet, "tcp");
+ ATF_REQUIRE(pp != NULL);
+
+ ATF_REQUIRE(pp->p_name != NULL);
+ ATF_REQUIRE(pp->p_aliases != NULL);
+ while (pp->p_aliases[n] != NULL)
+ ++n;
+ ATF_REQUIRE(n > 0);
+ ATF_REQUIRE(pp->p_proto != 0);
+
+ cap_close(capnet);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -1156,5 +1179,7 @@
ATF_TP_ADD_TC(tp, capnet__limits_connecttodns);
ATF_TP_ADD_TC(tp, capnet__limits_deprecated_connecttodns);
+ ATF_TP_ADD_TC(tp, capnet__getprotobyname);
+
return (atf_no_error());
}

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 19, 4:54 AM (21 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15924572
Default Alt Text
D26956.diff (8 KB)

Event Timeline