diff --git a/lib/libcasper/services/cap_net/cap_net.c b/lib/libcasper/services/cap_net/cap_net.c --- a/lib/libcasper/services/cap_net/cap_net.c +++ b/lib/libcasper/services/cap_net/cap_net.c @@ -288,7 +288,7 @@ const nvlist_t *nvlai; char nvlname[64]; nvlist_t *nvl; - int error, n; + int error, serrno, n; nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "getaddrinfo"); @@ -311,7 +311,10 @@ return (EAI_MEMORY); if (nvlist_get_number(nvl, "error") != 0) { error = (int)nvlist_get_number(nvl, "error"); + if (nvlist_exists_number(nvl, "errno")) + serrno = nvlist_get_number(nvl, "errno"); nvlist_destroy(nvl); + errno = (error == EAI_SYSTEM) ? serrno : 0; return (error); } @@ -350,7 +353,7 @@ char *host, size_t hostlen, char *serv, size_t servlen, int flags) { nvlist_t *nvl; - int error; + int error, serrno; nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "getnameinfo"); @@ -363,7 +366,10 @@ return (EAI_MEMORY); if (nvlist_get_number(nvl, "error") != 0) { error = (int)nvlist_get_number(nvl, "error"); + if (nvlist_exists_number(nvl, "errno")) + serrno = nvlist_get_number(nvl, "errno"); nvlist_destroy(nvl); + errno = (error == EAI_SYSTEM) ? serrno : 0; return (error); } @@ -858,19 +864,21 @@ char *host, *serv; size_t sabinsize, hostlen, servlen; socklen_t salen; - int error, flags; + int error, serrno, flags; const nvlist_t *funclimit; - if (!net_allowed_mode(limits, CAPNET_ADDR2NAME)) - return (ENOTCAPABLE); + host = serv = NULL; + if (!net_allowed_mode(limits, CAPNET_ADDR2NAME)) { + serrno = ENOTCAPABLE; + error = EAI_SYSTEM; + goto out; + } funclimit = NULL; if (limits != NULL) { funclimit = dnvlist_get_nvlist(limits, LIMIT_NV_ADDR2NAME, NULL); } - error = 0; - host = serv = NULL; memset(&sast, 0, sizeof(sast)); hostlen = (size_t)nvlist_get_number(nvlin, "hostlen"); @@ -921,6 +929,7 @@ error = getnameinfo((struct sockaddr *)&sast, salen, host, hostlen, serv, servlen, flags); + serrno = errno; if (error != 0) goto out; @@ -932,6 +941,8 @@ if (error != 0) { free(host); free(serv); + if (error == EAI_SYSTEM) + nvlist_add_number(nvlout, "errno", serrno); } return (error); } @@ -961,12 +972,15 @@ char nvlname[64]; nvlist_t *elem; unsigned int ii; - int error, family, n; + int error, serrno, family, n; const nvlist_t *funclimit; bool dnscache; - if (!net_allowed_mode(limits, CAPNET_NAME2ADDR)) - return (ENOTCAPABLE); + if (!net_allowed_mode(limits, CAPNET_NAME2ADDR)) { + serrno = ENOTCAPABLE; + error = EAI_SYSTEM; + goto out; + } dnscache = net_allowed_mode(limits, CAPNET_CONNECTDNS); funclimit = NULL; if (limits != NULL) { @@ -996,11 +1010,18 @@ family = AF_UNSPEC; } - if (!net_allowed_family(funclimit, family)) - return (ENOTCAPABLE); - if (!net_allowed_hosts(funclimit, hostname, servname)) - return (ENOTCAPABLE); + if (!net_allowed_family(funclimit, family)) { + errno = ENOTCAPABLE; + error = EAI_SYSTEM; + goto out; + } + if (!net_allowed_hosts(funclimit, hostname, servname)) { + errno = ENOTCAPABLE; + error = EAI_SYSTEM; + goto out; + } error = getaddrinfo(hostname, servname, hintsp, &res); + serrno = errno; if (error != 0) { goto out; } @@ -1019,6 +1040,8 @@ freeaddrinfo(res); error = 0; out: + if (error == EAI_SYSTEM) + nvlist_add_number(nvlout, "errno", serrno); return (error); }