Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107786642
D26956.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D26956.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D26956: libcasper/services/cap_net: Add cap_getprotobyname
Attached
Detach File
Event Timeline
Log In to Comment