carta
cap_gethostbyaddr(3)

cap_gethostbyaddr3

Library for networking in capability mode

Part of cap_bind(3).

Usage

int

int

int

int

struct hostent *

struct hostent *

struct hostent *

cap_net_limit_t *

int

void

cap_net_limit_t *

cap_net_limit_t *

cap_net_limit_t *

cap_net_limit_t *

cap_net_limit_t *

cap_net_limit_t *

Library

library “libcap_net”

Overview

The functions cap_bind(), cap_connect(), cap_getaddrinfo(), cap_getnameinfo(), cap_gethostbyname(), cap_gethostbyname2(), and cap_gethostbyaddr() provide a set of APIs equivalent to bind(2), connect(2), getaddrinfo(3), getnameinfo(3), gethostbyname(3), gethostbyname2(3), and gethostbyaddr(3) except that a connection to the system.net service needs to be provided.

These functions, as well as cap_net_limit(), are reentrant but not thread-safe. That is, they may be called from separate threads only with different cap_channel_t arguments or with synchronization.

Limits

By default, the cap_net capability provides unrestricted access to the network namespace. Applications typically only require access to a small portion of the network namespace: The cap_net_limit() function can be used to restrict access to the network. The cap_net_limit_init() returns an opaque limit handle used to store a list of capabilities. The mode restricts the functionality of the service. Modes are encoded using the following flags:

CAPNET_ADDR2NAME		reverse DNS lookups are allowed with
				cap_getnameinfo
CAPNET_NAME2ADDR		name resolution is allowed with
				cap_getaddrinfo
CAPNET_DEPRECATED_ADDR2NAME	reverse DNS lookups are allowed with
				cap_gethostbyaddr
CAPNET_DEPRECATED_NAME2ADDR	name resolution is allowed with
				cap_gethostbyname and cap_gethostbyname2
CAPNET_BIND			bind syscall is allowed
CAPNET_CONNECT			connect syscall is allowed
CAPNET_CONNECTDNS		connect syscall is allowed to the values
				returned from previous call to
				the cap_getaddrinfo or cap_gethostbyname

cap_net_limit_addr2name_family() limits the cap_getnameinfo() and cap_gethostbyaddr() to do reverse DNS lookups to specific family (AF_INET, AF_INET6, etc.)

cap_net_limit_addr2name() limits the cap_getnameinfo() and cap_gethostbyaddr() to do reverse DNS lookups only on those specific structures.

cap_net_limit_name2addr_family() limits the cap_getaddrinfo(), cap_gethostbyname() and cap_gethostbyname2() to do the name resolution on specific family (AF_INET, AF_INET6, etc.)

cap_net_limit_addr2name() restricts cap_getaddrinfo(), cap_gethostbyname() and cap_gethostbyname2() to a set of domains.

cap_net_limit_bind() limits cap_bind() to bind only on those specific structures.

cap_net_limit_connect() limits cap_connect() to connect only on those specific structures. If the CAPNET_CONNECTDNS is set the limits are extended to the values returned by cap_getaddrinfo(), cap_gethostbyname() and cap_gethostbyname2() In case of the cap_getaddrinfo() the restriction is strict. In case of the cap_gethostbyname() and cap_gethostbyname2() any port will be accepted in the cap_connect() function.

The cap_net_limit() will consume and apply the limits.

Once a set of limits is applied, subsequent calls to cap_net_limit() may only further restrict the service. Any call that would grant operations not currently permitted will fail.

If the cap_net_limit() was not called the rights may be freed using cap_net_free(). Multiple calls to cap_net_limit_addr2name_family(), cap_net_limit_addr2name(), cap_net_limit_name2addr_family(), cap_net_limit_name2addr(), cap_net_limit_connect(), and cap_net_limit_bind() is supported, each call is extending previous capabilities.

Examples

The following example first opens a capability to casper and then uses this capability to create the system.net casper service and uses it to resolve a host and connect to it.

cap_channel_t *capcas, *capnet;
cap_net_limit_t *limit;
int familylimit, error, s;
const char *host = "example.com";
struct addrinfo hints, *res;
/* Open capability to Casper. */
capcas = cap_init();
if (capcas == NULL)
	err(1, "Unable to contact Casper");
/* Cache NLA for gai_strerror. */
caph_cache_catpages();
/* Enter capability mode sandbox. */
if (caph_enter_casper() < 0)
	err(1, "Unable to enter capability mode");
/* Use Casper capability to create capability to the system.net service. */
capnet = cap_service_open(capcas, "system.net");
if (capnet == NULL)
	err(1, "Unable to open system.net service");
/* Close Casper capability. */
cap_close(capcas);
/* Limit system.net to resolve 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.");
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.");
/* Find IP addresses for the given host. */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
error = cap_getaddrinfo(capnet, host, "80", &hints, &res);
if (error != 0)
	errx(1, "cap_getaddrinfo(): %s: %s", host, gai_strerror(error));
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0)
	err(1, "Unable to create socket");
if (cap_connect(capnet, s, res->ai_addr,  res->ai_addrlen) < 0)
	err(1, "Unable to connect to host");

History

  • FreeBSD 16.0-CURRENT (2026-10-27): the text shown here
  • FreeBSD 15.1-RELEASE to FreeBSD 15.0-RELEASE
  • FreeBSD 14.5-RELEASE
  • FreeBSD 14.4-RELEASE to FreeBSD 14.3-RELEASE
  • FreeBSD 14.2-RELEASE to FreeBSD 14.1-RELEASE
  • FreeBSD 14.0-RELEASE
  • FreeBSD 13.5-RELEASE
  • FreeBSD 13.4-RELEASE to FreeBSD 13.3-RELEASE
  • FreeBSD 13.2-RELEASE to FreeBSD 13.1-RELEASE
  • FreeBSD 13.0-RELEASE
  • FreeBSD 12.4-RELEASE
  • FreeBSD 12.3-RELEASE
  • FreeBSD 12.2-RELEASE
  • FreeBSD 12.1-RELEASE
  • FreeBSD 12.0-RELEASE

Authors

Mariusz Zaborski ⟨[email protected]⟩

From base 16.0-CURRENT-20261027-61c70dc16a79 in FreeBSD 16.0-CURRENT (2026-10-27). Parsed by carta from the page's mdoc source.