mirror of
https://github.com/opnsense/src.git
synced 2026-06-10 17:22:46 -04:00
sockstat: add libxo support
Sponsored by: Google, LLC (GSoC 2025) MFC after: 2 weeks Reviewed by: asomers Pull Request: https://github.com/freebsd/freebsd-src/pull/1770 Relnotes: yes
This commit is contained in:
parent
74072e9f16
commit
7b35b4d196
3 changed files with 306 additions and 180 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
PROG= sockstat
|
||||
|
||||
LIBADD= jail
|
||||
LIBADD= jail xo
|
||||
|
||||
.if ${MK_CASPER} != "no"
|
||||
LIBADD+= casper
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd June 30, 2025
|
||||
.Dd July 17, 2025
|
||||
.Dt SOCKSTAT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
.Nd list open sockets
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl -libxo
|
||||
.Op Fl 46ACcfIiLlnqSsUuvw
|
||||
.Op Fl j Ar jail
|
||||
.Op Fl p Ar ports
|
||||
|
|
@ -46,6 +47,13 @@ domain sockets.
|
|||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width Fl
|
||||
.It Fl -libxo
|
||||
Generate output via
|
||||
.Xr libxo 3
|
||||
in a selection of different human and machine readable formats.
|
||||
See
|
||||
.Xr xo_options 7
|
||||
for details on command line arguments.
|
||||
.It Fl 4
|
||||
Show
|
||||
.Dv AF_INET
|
||||
|
|
@ -229,6 +237,11 @@ Show TCP IPv6 sockets which are listening and connected (default):
|
|||
.Bd -literal -offset indent
|
||||
$ sockstat -6 -P tcp
|
||||
.Ed
|
||||
.Pp
|
||||
Show all sockets in JSON format with neat alignment:
|
||||
.Bd -literal -offset indent
|
||||
$ sockstat --libxo json,pretty
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr fstat 1 ,
|
||||
.Xr netstat 1 ,
|
||||
|
|
@ -237,6 +250,8 @@ $ sockstat -6 -P tcp
|
|||
.Xr inet 4 ,
|
||||
.Xr inet6 4 ,
|
||||
.Xr protocols 5
|
||||
.Xr libxo 3 ,
|
||||
.Xr xo_options 7
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@
|
|||
|
||||
#include <capsicum_helpers.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <jail.h>
|
||||
|
|
@ -67,6 +66,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libxo/xo.h>
|
||||
|
||||
#include <libcasper.h>
|
||||
#include <casper/cap_net.h>
|
||||
|
|
@ -74,6 +74,7 @@
|
|||
#include <casper/cap_pwd.h>
|
||||
#include <casper/cap_sysctl.h>
|
||||
|
||||
#define SOCKSTAT_XO_VERSION "1"
|
||||
#define sstosin(ss) ((struct sockaddr_in *)(ss))
|
||||
#define sstosin6(ss) ((struct sockaddr_in6 *)(ss))
|
||||
#define sstosun(ss) ((struct sockaddr_un *)(ss))
|
||||
|
|
@ -197,7 +198,7 @@ static bool
|
|||
_check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
|
||||
{
|
||||
if (received_size != expected_size) {
|
||||
warnx("%s size mismatch: expected %zd, received %zd",
|
||||
xo_warnx("%s size mismatch: expected %zd, received %zd",
|
||||
struct_name, expected_size, received_size);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -209,7 +210,7 @@ static void
|
|||
_enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name)
|
||||
{
|
||||
if (received_size != expected_size) {
|
||||
errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
|
||||
xo_errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
|
||||
struct_name, expected_size, received_size);
|
||||
}
|
||||
}
|
||||
|
|
@ -227,7 +228,7 @@ get_proto_type(const char *proto)
|
|||
else
|
||||
pent = getprotobyname(proto);
|
||||
if (pent == NULL) {
|
||||
warn("cap_getprotobyname");
|
||||
xo_warn("cap_getprotobyname");
|
||||
return (-1);
|
||||
}
|
||||
return (pent->p_proto);
|
||||
|
|
@ -248,7 +249,7 @@ init_protos(int num)
|
|||
}
|
||||
|
||||
if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
|
||||
err(1, "malloc");
|
||||
xo_err(1, "malloc");
|
||||
numprotos = proto_count;
|
||||
}
|
||||
|
||||
|
|
@ -282,17 +283,17 @@ parse_ports(const char *portspec)
|
|||
|
||||
if (ports == NULL)
|
||||
if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
|
||||
err(1, "calloc()");
|
||||
xo_err(1, "calloc()");
|
||||
p = portspec;
|
||||
while (*p != '\0') {
|
||||
if (!isdigit(*p))
|
||||
errx(1, "syntax error in port range");
|
||||
xo_errx(1, "syntax error in port range");
|
||||
for (q = p; *q != '\0' && isdigit(*q); ++q)
|
||||
/* nothing */ ;
|
||||
for (port = 0; p < q; ++p)
|
||||
port = port * 10 + digittoint(*p);
|
||||
if (port < 0 || port > 65535)
|
||||
errx(1, "invalid port number");
|
||||
xo_errx(1, "invalid port number");
|
||||
SET_PORT(port);
|
||||
switch (*p) {
|
||||
case '-':
|
||||
|
|
@ -310,7 +311,7 @@ parse_ports(const char *portspec)
|
|||
for (end = 0; p < q; ++p)
|
||||
end = end * 10 + digittoint(*p);
|
||||
if (end < port || end > 65535)
|
||||
errx(1, "invalid port number");
|
||||
xo_errx(1, "invalid port number");
|
||||
while (port++ < end)
|
||||
SET_PORT(port);
|
||||
if (*p == ',')
|
||||
|
|
@ -395,15 +396,15 @@ gather_sctp(void)
|
|||
varname = "net.inet.sctp.assoclist";
|
||||
if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
err(1, "cap_sysctlbyname()");
|
||||
xo_err(1, "cap_sysctlbyname()");
|
||||
return;
|
||||
}
|
||||
if ((buf = (char *)malloc(len)) == NULL) {
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
return;
|
||||
}
|
||||
if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
|
||||
err(1, "cap_sysctlbyname()");
|
||||
xo_err(1, "cap_sysctlbyname()");
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
|
@ -411,7 +412,7 @@ gather_sctp(void)
|
|||
offset = sizeof(struct xsctp_inpcb);
|
||||
while ((offset < len) && (xinpcb->last == 0)) {
|
||||
if ((sock = calloc(1, sizeof *sock)) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
sock->socket = xinpcb->socket;
|
||||
sock->proto = IPPROTO_SCTP;
|
||||
sock->protoname = "sctp";
|
||||
|
|
@ -439,7 +440,7 @@ gather_sctp(void)
|
|||
if (xladdr->last == 1)
|
||||
break;
|
||||
if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
switch (xladdr->address.sa.sa_family) {
|
||||
case AF_INET:
|
||||
#define __IN_IS_ADDR_LOOPBACK(pina) \
|
||||
|
|
@ -461,7 +462,7 @@ gather_sctp(void)
|
|||
htons(xinpcb->local_port));
|
||||
break;
|
||||
default:
|
||||
errx(1, "address family %d not supported",
|
||||
xo_errx(1, "address family %d not supported",
|
||||
xladdr->address.sa.sa_family);
|
||||
}
|
||||
laddr->next = NULL;
|
||||
|
|
@ -474,7 +475,7 @@ gather_sctp(void)
|
|||
if (sock->laddr == NULL) {
|
||||
if ((sock->laddr =
|
||||
calloc(1, sizeof(struct addr))) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
sock->laddr->address.ss_family = sock->family;
|
||||
if (sock->family == AF_INET)
|
||||
sock->laddr->address.ss_len =
|
||||
|
|
@ -485,7 +486,7 @@ gather_sctp(void)
|
|||
local_all_loopback = 0;
|
||||
}
|
||||
if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
sock->faddr->address.ss_family = sock->family;
|
||||
if (sock->family == AF_INET)
|
||||
sock->faddr->address.ss_len =
|
||||
|
|
@ -512,7 +513,7 @@ gather_sctp(void)
|
|||
no_stcb = 0;
|
||||
if (opt_c) {
|
||||
if ((sock = calloc(1, sizeof *sock)) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
sock->socket = xinpcb->socket;
|
||||
sock->proto = IPPROTO_SCTP;
|
||||
sock->protoname = "sctp";
|
||||
|
|
@ -542,7 +543,7 @@ gather_sctp(void)
|
|||
continue;
|
||||
laddr = calloc(1, sizeof(struct addr));
|
||||
if (laddr == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
switch (xladdr->address.sa.sa_family) {
|
||||
case AF_INET:
|
||||
#define __IN_IS_ADDR_LOOPBACK(pina) \
|
||||
|
|
@ -564,7 +565,7 @@ gather_sctp(void)
|
|||
htons(xstcb->local_port));
|
||||
break;
|
||||
default:
|
||||
errx(1,
|
||||
xo_errx(1,
|
||||
"address family %d not supported",
|
||||
xladdr->address.sa.sa_family);
|
||||
}
|
||||
|
|
@ -587,7 +588,7 @@ gather_sctp(void)
|
|||
continue;
|
||||
faddr = calloc(1, sizeof(struct addr));
|
||||
if (faddr == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
switch (xraddr->address.sa.sa_family) {
|
||||
case AF_INET:
|
||||
#define __IN_IS_ADDR_LOOPBACK(pina) \
|
||||
|
|
@ -609,7 +610,7 @@ gather_sctp(void)
|
|||
htons(xstcb->remote_port));
|
||||
break;
|
||||
default:
|
||||
errx(1,
|
||||
xo_errx(1,
|
||||
"address family %d not supported",
|
||||
xraddr->address.sa.sa_family);
|
||||
}
|
||||
|
|
@ -673,7 +674,7 @@ gather_inet(int proto)
|
|||
protoname = "div";
|
||||
break;
|
||||
default:
|
||||
errx(1, "protocol %d not supported", proto);
|
||||
xo_errx(1, "protocol %d not supported", proto);
|
||||
}
|
||||
|
||||
buf = NULL;
|
||||
|
|
@ -682,7 +683,7 @@ gather_inet(int proto)
|
|||
do {
|
||||
for (;;) {
|
||||
if ((buf = realloc(buf, bufsize)) == NULL)
|
||||
err(1, "realloc()");
|
||||
xo_err(1, "realloc()");
|
||||
len = bufsize;
|
||||
if (cap_sysctlbyname(capsysctl, varname, buf, &len,
|
||||
NULL, 0) == 0)
|
||||
|
|
@ -690,7 +691,7 @@ gather_inet(int proto)
|
|||
if (errno == ENOENT)
|
||||
goto out;
|
||||
if (errno != ENOMEM || len != bufsize)
|
||||
err(1, "cap_sysctlbyname()");
|
||||
xo_err(1, "cap_sysctlbyname()");
|
||||
bufsize *= 2;
|
||||
}
|
||||
xig = (struct xinpgen *)buf;
|
||||
|
|
@ -701,7 +702,7 @@ gather_inet(int proto)
|
|||
} while (xig->xig_gen != exig->xig_gen && retry--);
|
||||
|
||||
if (xig->xig_gen != exig->xig_gen && opt_v)
|
||||
warnx("warning: data may be inconsistent");
|
||||
xo_warnx("warning: data may be inconsistent");
|
||||
|
||||
for (;;) {
|
||||
xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
|
||||
|
|
@ -722,7 +723,7 @@ gather_inet(int proto)
|
|||
goto out;
|
||||
break;
|
||||
default:
|
||||
errx(1, "protocol %d not supported", proto);
|
||||
xo_errx(1, "protocol %d not supported", proto);
|
||||
}
|
||||
so = &xip->xi_socket;
|
||||
if ((xip->inp_vflag & vflag) == 0)
|
||||
|
|
@ -748,15 +749,15 @@ gather_inet(int proto)
|
|||
continue;
|
||||
} else {
|
||||
if (opt_v)
|
||||
warnx("invalid vflag 0x%x", xip->inp_vflag);
|
||||
xo_warnx("invalid vflag 0x%x", xip->inp_vflag);
|
||||
continue;
|
||||
}
|
||||
if ((sock = calloc(1, sizeof(*sock))) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
if ((laddr = calloc(1, sizeof *laddr)) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
if ((faddr = calloc(1, sizeof *faddr)) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
sock->socket = so->xso_so;
|
||||
sock->pcb = so->so_pcb;
|
||||
sock->splice_socket = so->so_splice_so;
|
||||
|
|
@ -822,7 +823,9 @@ gather_unix(int proto)
|
|||
break;
|
||||
case SOCK_SEQPACKET:
|
||||
varname = "net.local.seqpacket.pcblist";
|
||||
protoname = "seqpac";
|
||||
protoname = (xo_get_style(NULL) == XO_STYLE_TEXT)
|
||||
? "seqpac"
|
||||
: "seqpacket";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
|
|
@ -833,13 +836,13 @@ gather_unix(int proto)
|
|||
do {
|
||||
for (;;) {
|
||||
if ((buf = realloc(buf, bufsize)) == NULL)
|
||||
err(1, "realloc()");
|
||||
xo_err(1, "realloc()");
|
||||
len = bufsize;
|
||||
if (cap_sysctlbyname(capsysctl, varname, buf, &len,
|
||||
NULL, 0) == 0)
|
||||
break;
|
||||
if (errno != ENOMEM || len != bufsize)
|
||||
err(1, "cap_sysctlbyname()");
|
||||
xo_err(1, "cap_sysctlbyname()");
|
||||
bufsize *= 2;
|
||||
}
|
||||
xug = (struct xunpgen *)buf;
|
||||
|
|
@ -851,7 +854,7 @@ gather_unix(int proto)
|
|||
} while (xug->xug_gen != exug->xug_gen && retry--);
|
||||
|
||||
if (xug->xug_gen != exug->xug_gen && opt_v)
|
||||
warnx("warning: data may be inconsistent");
|
||||
xo_warnx("warning: data may be inconsistent");
|
||||
|
||||
for (;;) {
|
||||
xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
|
||||
|
|
@ -864,11 +867,11 @@ gather_unix(int proto)
|
|||
(xup->unp_conn != 0 && !opt_c))
|
||||
continue;
|
||||
if ((sock = calloc(1, sizeof(*sock))) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
if ((laddr = calloc(1, sizeof *laddr)) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
if ((faddr = calloc(1, sizeof *faddr)) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
sock->socket = xup->xu_socket.xso_so;
|
||||
sock->pcb = xup->xu_unpp;
|
||||
sock->proto = proto;
|
||||
|
|
@ -899,21 +902,21 @@ getfiles(void)
|
|||
|
||||
olen = len = sizeof(*xfiles);
|
||||
if ((xfiles = malloc(len)) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0)
|
||||
== -1) {
|
||||
if (errno != ENOMEM || len != olen)
|
||||
err(1, "cap_sysctlbyname()");
|
||||
xo_err(1, "cap_sysctlbyname()");
|
||||
olen = len *= 2;
|
||||
if ((xfiles = realloc(xfiles, len)) == NULL)
|
||||
err(1, "realloc()");
|
||||
xo_err(1, "realloc()");
|
||||
}
|
||||
if (len > 0)
|
||||
enforce_ksize(xfiles->xf_size, struct xfile);
|
||||
nfiles = len / sizeof(*xfiles);
|
||||
|
||||
if ((files = malloc(nfiles * sizeof(struct file))) == NULL)
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
|
||||
for (int i = 0; i < nfiles; i++) {
|
||||
files[i].xf_data = xfiles[i].xf_data;
|
||||
|
|
@ -932,6 +935,7 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
|
|||
struct sockaddr_un *sun;
|
||||
char addrstr[NI_MAXHOST] = { '\0', '\0' };
|
||||
int error, off, port = 0;
|
||||
const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT);
|
||||
|
||||
switch (ss->ss_family) {
|
||||
case AF_INET:
|
||||
|
|
@ -947,6 +951,11 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
|
|||
case AF_UNIX:
|
||||
sun = sstosun(ss);
|
||||
off = (int)((char *)&sun->sun_path - (char *)sun);
|
||||
if (!is_text_style) {
|
||||
xo_emit("{:path/%.*s}", sun->sun_len - off,
|
||||
sun->sun_path);
|
||||
return 0;
|
||||
}
|
||||
return snprintf(buf, bufsize, "%.*s",
|
||||
sun->sun_len - off, sun->sun_path);
|
||||
}
|
||||
|
|
@ -954,7 +963,12 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
|
|||
error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
|
||||
addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
|
||||
if (error)
|
||||
errx(1, "cap_getnameinfo()");
|
||||
xo_errx(1, "cap_getnameinfo()");
|
||||
}
|
||||
if (!is_text_style) {
|
||||
xo_emit("{:address/%s}", addrstr);
|
||||
xo_emit("{:port/%d}", port);
|
||||
return 0;
|
||||
}
|
||||
if (port == 0)
|
||||
return snprintf(buf, bufsize, "%s:*", addrstr);
|
||||
|
|
@ -977,7 +991,7 @@ getprocname(pid_t pid)
|
|||
== -1) {
|
||||
/* Do not warn if the process exits before we get its name. */
|
||||
if (errno != ESRCH)
|
||||
warn("cap_sysctl()");
|
||||
xo_warn("cap_sysctl()");
|
||||
return ("??");
|
||||
}
|
||||
return (proc.ki_comm);
|
||||
|
|
@ -999,7 +1013,7 @@ getprocjid(pid_t pid)
|
|||
== -1) {
|
||||
/* Do not warn if the process exits before we get its jid. */
|
||||
if (errno != ESRCH)
|
||||
warn("cap_sysctl()");
|
||||
xo_warn("cap_sysctl()");
|
||||
return (-1);
|
||||
}
|
||||
return (proc.ki_jid);
|
||||
|
|
@ -1099,13 +1113,15 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
|
|||
#define SAFESIZE (buf == NULL ? 0 : bufsize - pos)
|
||||
|
||||
size_t pos = 0;
|
||||
/* Remote peer we connect(2) to, if any. */
|
||||
const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT);
|
||||
if (faddr->conn != 0) {
|
||||
/* Remote peer we connect(2) to, if any. */
|
||||
struct sock *p;
|
||||
pos += strlcpy(SAFEBUF, "-> ", SAFESIZE);
|
||||
if (is_text_style)
|
||||
pos += strlcpy(SAFEBUF, "-> ", SAFESIZE);
|
||||
p = RB_FIND(pcbs_t, &pcbs,
|
||||
&(struct sock){ .pcb = faddr->conn });
|
||||
if (__predict_false(p == NULL)) {
|
||||
if (__predict_false(p == NULL) && is_text_style) {
|
||||
/* XXGL: can this happen at all? */
|
||||
pos += snprintf(SAFEBUF, SAFESIZE, "??");
|
||||
} else if (p->laddr->address.ss_len == 0) {
|
||||
|
|
@ -1114,34 +1130,52 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
|
|||
&(struct file){ .xf_data =
|
||||
p->socket });
|
||||
if (f != NULL) {
|
||||
pos += snprintf(SAFEBUF, SAFESIZE, "[%lu %d]",
|
||||
(u_long)f->xf_pid, f->xf_fd);
|
||||
if (is_text_style) {
|
||||
pos += snprintf(SAFEBUF, SAFESIZE,
|
||||
"[%lu %d]", (u_long)f->xf_pid,
|
||||
f->xf_fd);
|
||||
} else {
|
||||
xo_open_list("connections");
|
||||
xo_open_instance("connections");
|
||||
xo_emit("{:pid/%lu}", (u_long)f->xf_pid);
|
||||
xo_emit("{:fd/%d}", f->xf_fd);
|
||||
xo_close_instance("connections");
|
||||
xo_close_list("connections");
|
||||
}
|
||||
}
|
||||
} else
|
||||
pos += formataddr(&p->laddr->address,
|
||||
SAFEBUF, SAFESIZE);
|
||||
}
|
||||
/* Remote peer(s) connect(2)ed to us, if any. */
|
||||
if (faddr->firstref != 0) {
|
||||
} else if (faddr->firstref != 0) {
|
||||
/* Remote peer(s) connect(2)ed to us, if any. */
|
||||
struct sock *p;
|
||||
struct file *f;
|
||||
kvaddr_t ref = faddr->firstref;
|
||||
bool fref = true;
|
||||
|
||||
pos += snprintf(SAFEBUF, SAFESIZE, " <- ");
|
||||
|
||||
if (is_text_style)
|
||||
pos += snprintf(SAFEBUF, SAFESIZE, " <- ");
|
||||
xo_open_list("connections");
|
||||
while ((p = RB_FIND(pcbs_t, &pcbs,
|
||||
&(struct sock){ .pcb = ref })) != 0) {
|
||||
f = RB_FIND(files_t, &ftree,
|
||||
&(struct file){ .xf_data = p->socket });
|
||||
if (f != NULL) {
|
||||
pos += snprintf(SAFEBUF, SAFESIZE,
|
||||
"%s[%lu %d]", fref ? "" : ",",
|
||||
(u_long)f->xf_pid, f->xf_fd);
|
||||
if (is_text_style) {
|
||||
pos += snprintf(SAFEBUF, SAFESIZE,
|
||||
"%s[%lu %d]", fref ? "" : ",",
|
||||
(u_long)f->xf_pid, f->xf_fd);
|
||||
} else {
|
||||
xo_open_instance("connections");
|
||||
xo_emit("{:pid/%lu}", (u_long)f->xf_pid);
|
||||
xo_emit("{:fd/%d}", f->xf_fd);
|
||||
xo_close_instance("connections");
|
||||
}
|
||||
}
|
||||
ref = p->faddr->nextref;
|
||||
fref = false;
|
||||
}
|
||||
xo_close_list("connections");
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
|
@ -1183,7 +1217,7 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
|
|||
while (laddr != NULL || faddr != NULL) {
|
||||
if (opt_w && s->family == AF_UNIX) {
|
||||
if ((laddr == NULL) || (faddr == NULL))
|
||||
errx(1, "laddr = %p or faddr = %p is NULL",
|
||||
xo_errx(1, "laddr = %p or faddr = %p is NULL",
|
||||
(void *)laddr, (void *)faddr);
|
||||
if (laddr->address.ss_len > 0)
|
||||
len = formataddr(&laddr->address, NULL, 0);
|
||||
|
|
@ -1298,6 +1332,7 @@ calculate_column_widths(struct col_widths *cw)
|
|||
struct sock *s;
|
||||
struct passwd *pwd;
|
||||
|
||||
cap_setpassent(cappwd, 1);
|
||||
for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
|
||||
if (xf->xf_data == 0)
|
||||
continue;
|
||||
|
|
@ -1345,65 +1380,104 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
|
|||
laddr = s->laddr;
|
||||
faddr = s->faddr;
|
||||
first = true;
|
||||
const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT);
|
||||
|
||||
snprintf(buf, bufsize, "%s%s%s",
|
||||
s->protoname,
|
||||
s->vflag & INP_IPV4 ? "4" : "",
|
||||
s->vflag & INP_IPV6 ? "6" : "");
|
||||
printf(" %-*s", cw->proto, buf);
|
||||
xo_emit(" {:proto/%-*s}", cw->proto, buf);
|
||||
while (laddr != NULL || faddr != NULL) {
|
||||
if (s->family == AF_UNIX) {
|
||||
if ((laddr == NULL) || (faddr == NULL))
|
||||
errx(1, "laddr = %p or faddr = %p is NULL",
|
||||
xo_errx(1, "laddr = %p or faddr = %p is NULL",
|
||||
(void *)laddr, (void *)faddr);
|
||||
if (laddr->address.ss_len > 0)
|
||||
if (laddr->address.ss_len > 0) {
|
||||
xo_open_container("local");
|
||||
formataddr(&laddr->address, buf, bufsize);
|
||||
else if (laddr->address.ss_len == 0 && faddr->conn == 0)
|
||||
strlcpy(buf, "(not connected)", bufsize);
|
||||
else
|
||||
strlcpy(buf, "??", bufsize);
|
||||
printf(" %-*.*s", cw->local_addr, cw->local_addr, buf);
|
||||
if (format_unix_faddr(faddr, buf, bufsize) == 0)
|
||||
strlcpy(buf, "??", bufsize);
|
||||
printf(" %-*.*s", cw->foreign_addr,
|
||||
cw->foreign_addr, buf);
|
||||
if (is_text_style) {
|
||||
xo_emit(" {:/%-*.*s}", cw->local_addr,
|
||||
cw->local_addr, buf);
|
||||
}
|
||||
xo_close_container("local");
|
||||
} else if (laddr->address.ss_len == 0 &&
|
||||
faddr->conn == 0 && is_text_style) {
|
||||
xo_emit(" {:/%-*.*s}", cw->local_addr,
|
||||
cw->local_addr, "(not connected)");
|
||||
} else if (is_text_style) {
|
||||
xo_emit(" {:/%-*.*s}", cw->local_addr,
|
||||
cw->local_addr, "??");
|
||||
}
|
||||
if (faddr->conn != 0 || faddr->firstref != 0) {
|
||||
xo_open_container("foreign");
|
||||
int len = format_unix_faddr(faddr, buf,
|
||||
bufsize);
|
||||
if (len == 0 && is_text_style)
|
||||
xo_emit(" {:/%-*s}",
|
||||
cw->foreign_addr, "??");
|
||||
else if (is_text_style)
|
||||
xo_emit(" {:/%-*.*s}", cw->foreign_addr,
|
||||
cw->foreign_addr, buf);
|
||||
xo_close_container("foreign");
|
||||
} else if (is_text_style)
|
||||
xo_emit(" {:/%-*s}", cw->foreign_addr, "??");
|
||||
} else {
|
||||
if (laddr != NULL)
|
||||
if (laddr != NULL) {
|
||||
xo_open_container("local");
|
||||
formataddr(&laddr->address, buf, bufsize);
|
||||
else
|
||||
strlcpy(buf, "??", bufsize);
|
||||
printf(" %-*.*s", cw->local_addr, cw->local_addr, buf);
|
||||
if (faddr != NULL)
|
||||
if (is_text_style) {
|
||||
xo_emit(" {:/%-*.*s}", cw->local_addr,
|
||||
cw->local_addr, buf);
|
||||
}
|
||||
xo_close_container("local");
|
||||
} else if (is_text_style)
|
||||
xo_emit(" {:/%-*.*s}", cw->local_addr,
|
||||
cw->local_addr, "??");
|
||||
if (faddr != NULL) {
|
||||
xo_open_container("foreign");
|
||||
formataddr(&faddr->address, buf, bufsize);
|
||||
else
|
||||
strlcpy(buf, "??", bufsize);
|
||||
printf(" %-*.*s", cw->foreign_addr,
|
||||
cw->foreign_addr, buf);
|
||||
if (is_text_style) {
|
||||
xo_emit(" {:/%-*.*s}", cw->foreign_addr,
|
||||
cw->foreign_addr, buf);
|
||||
}
|
||||
xo_close_container("foreign");
|
||||
} else if (is_text_style) {
|
||||
xo_emit(" {:/%-*.*s}", cw->foreign_addr,
|
||||
cw->foreign_addr, "??");
|
||||
}
|
||||
}
|
||||
if (opt_A) {
|
||||
snprintf(buf, bufsize, "%#*" PRIx64,
|
||||
cw->pcb_kva, s->pcb);
|
||||
xo_emit(" {:pcb-kva/%s}", buf);
|
||||
}
|
||||
if (opt_A)
|
||||
printf(" %#*" PRIx64, cw->pcb_kva, s->pcb);
|
||||
if (opt_f)
|
||||
printf(" %*d", cw->fib, s->fibnum);
|
||||
xo_emit(" {:fib/%*d}", cw->fib, s->fibnum);
|
||||
if (opt_I) {
|
||||
if (s->splice_socket != 0) {
|
||||
struct sock *sp;
|
||||
sp = RB_FIND(socks_t, &socks, &(struct sock)
|
||||
{ .socket = s->splice_socket });
|
||||
if (sp != NULL)
|
||||
if (sp != NULL) {
|
||||
xo_open_container("splice");
|
||||
formataddr(&sp->laddr->address,
|
||||
buf, bufsize);
|
||||
else
|
||||
xo_close_container("splice");
|
||||
} else if (is_text_style)
|
||||
strlcpy(buf, "??", bufsize);
|
||||
} else
|
||||
} else if (is_text_style)
|
||||
strlcpy(buf, "??", bufsize);
|
||||
printf(" %-*s", cw->splice_address, buf);
|
||||
if (is_text_style)
|
||||
xo_emit(" {:/%-*s}", cw->splice_address, buf);
|
||||
}
|
||||
if (opt_i) {
|
||||
if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
|
||||
printf(" %*" PRIu64, cw->inp_gencnt,
|
||||
{
|
||||
snprintf(buf, bufsize, "%" PRIu64,
|
||||
s->inp_gencnt);
|
||||
else
|
||||
printf(" %*s", cw->inp_gencnt, "??");
|
||||
xo_emit(" {:id/%*s}", cw->inp_gencnt, buf);
|
||||
} else if (is_text_style)
|
||||
xo_emit(" {:/%*s}", cw->inp_gencnt, "??");
|
||||
}
|
||||
if (opt_U) {
|
||||
if (faddr != NULL &&
|
||||
|
|
@ -1414,10 +1488,10 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
|
|||
(s->proto == IPPROTO_TCP &&
|
||||
s->state != TCPS_CLOSED &&
|
||||
s->state != TCPS_LISTEN))) {
|
||||
printf(" %*u", cw->encaps,
|
||||
xo_emit(" {:encaps/%*u}", cw->encaps,
|
||||
ntohs(faddr->encaps_port));
|
||||
} else
|
||||
printf(" %*s", cw->encaps, "??");
|
||||
} else if (is_text_style)
|
||||
xo_emit(" {:/%*s}", cw->encaps, "??");
|
||||
}
|
||||
if (opt_s) {
|
||||
if (faddr != NULL &&
|
||||
|
|
@ -1425,10 +1499,10 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
|
|||
s->state != SCTP_CLOSED &&
|
||||
s->state != SCTP_BOUND &&
|
||||
s->state != SCTP_LISTEN) {
|
||||
printf(" %-*s", cw->path_state,
|
||||
xo_emit(" {:path-state/%-*s}", cw->path_state,
|
||||
sctp_path_state(faddr->state));
|
||||
} else
|
||||
printf(" %-*s", cw->path_state, "??");
|
||||
} else if (is_text_style)
|
||||
xo_emit(" {:/%-*s}", cw->path_state, "??");
|
||||
}
|
||||
if (first) {
|
||||
if (opt_s) {
|
||||
|
|
@ -1436,47 +1510,52 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
|
|||
s->proto == IPPROTO_TCP) {
|
||||
switch (s->proto) {
|
||||
case IPPROTO_SCTP:
|
||||
printf(" %-*s", cw->conn_state,
|
||||
sctp_conn_state(s->state));
|
||||
xo_emit(" {:path-state/%-*s}",
|
||||
cw->path_state,
|
||||
sctp_path_state(
|
||||
faddr->state));
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
if (s->state >= 0 &&
|
||||
s->state < TCP_NSTATES)
|
||||
printf(" %-*s",
|
||||
cw->conn_state,
|
||||
tcpstates[s->state]);
|
||||
else
|
||||
printf(" %-*s",
|
||||
cw->conn_state, "??");
|
||||
xo_emit(" {:conn-state/%-*s}",
|
||||
cw->conn_state,
|
||||
tcpstates[s->state]);
|
||||
else if (is_text_style)
|
||||
xo_emit(" {:/%-*s}",
|
||||
cw->conn_state, "??");
|
||||
break;
|
||||
}
|
||||
} else
|
||||
printf(" %-*s", cw->conn_state, "??");
|
||||
} else if (is_text_style)
|
||||
xo_emit(" {:/%-*s}",
|
||||
cw->conn_state, "??");
|
||||
}
|
||||
if (opt_S) {
|
||||
if (s->proto == IPPROTO_TCP)
|
||||
printf(" %-*s", cw->stack, s->stack);
|
||||
else
|
||||
printf(" %-*s", cw->stack, "??");
|
||||
xo_emit(" {:stack/%-*s}",
|
||||
cw->stack, s->stack);
|
||||
else if (is_text_style)
|
||||
xo_emit(" {:/%-*s}",
|
||||
cw->stack, "??");
|
||||
}
|
||||
if (opt_C) {
|
||||
if (s->proto == IPPROTO_TCP)
|
||||
printf(" %-*s", cw->cc, s->cc);
|
||||
else
|
||||
printf(" %-*s", cw->cc, "??");
|
||||
xo_emit(" {:cc/%-*s}", cw->cc, s->cc);
|
||||
else if (is_text_style)
|
||||
xo_emit(" {:/%-*s}", cw->cc, "??");
|
||||
}
|
||||
}
|
||||
if (laddr != NULL)
|
||||
laddr = laddr->next;
|
||||
if (faddr != NULL)
|
||||
faddr = faddr->next;
|
||||
if (laddr != NULL || faddr != NULL)
|
||||
printf("%-*s %-*s %-*s %-*s %-*s", cw->user, "",
|
||||
cw->command, "", cw->pid, "", cw->fd, "",
|
||||
cw->proto, "");
|
||||
if (is_text_style && (laddr != NULL || faddr != NULL))
|
||||
xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}",
|
||||
cw->user, "??", cw->command, "??",
|
||||
cw->pid, "??", cw->fd, "??");
|
||||
first = false;
|
||||
}
|
||||
printf("\n");
|
||||
xo_emit("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1490,56 +1569,63 @@ display(void)
|
|||
const size_t bufsize = 512;
|
||||
void *buf;
|
||||
if ((buf = (char *)malloc(bufsize)) == NULL) {
|
||||
err(1, "malloc()");
|
||||
xo_err(1, "malloc()");
|
||||
return;
|
||||
}
|
||||
|
||||
cw = (struct col_widths) {
|
||||
.user = strlen("USER"),
|
||||
.command = 10,
|
||||
.pid = strlen("PID"),
|
||||
.fd = strlen("FD"),
|
||||
.proto = strlen("PROTO"),
|
||||
.local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21,
|
||||
.foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21,
|
||||
.pcb_kva = 18,
|
||||
.fib = strlen("FIB"),
|
||||
.splice_address = strlen("SPLICE ADDRESS"),
|
||||
.inp_gencnt = strlen("ID"),
|
||||
.encaps = strlen("ENCAPS"),
|
||||
.path_state = strlen("PATH STATE"),
|
||||
.conn_state = strlen("CONN STATE"),
|
||||
.stack = strlen("STACK"),
|
||||
.cc = strlen("CC"),
|
||||
};
|
||||
calculate_column_widths(&cw);
|
||||
if (xo_get_style(NULL) == XO_STYLE_TEXT) {
|
||||
cw = (struct col_widths) {
|
||||
.user = strlen("USER"),
|
||||
.command = 10,
|
||||
.pid = strlen("PID"),
|
||||
.fd = strlen("FD"),
|
||||
.proto = strlen("PROTO"),
|
||||
.local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21,
|
||||
.foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21,
|
||||
.pcb_kva = 18,
|
||||
.fib = strlen("FIB"),
|
||||
.splice_address = strlen("SPLICE ADDRESS"),
|
||||
.inp_gencnt = strlen("ID"),
|
||||
.encaps = strlen("ENCAPS"),
|
||||
.path_state = strlen("PATH STATE"),
|
||||
.conn_state = strlen("CONN STATE"),
|
||||
.stack = strlen("STACK"),
|
||||
.cc = strlen("CC"),
|
||||
};
|
||||
calculate_column_widths(&cw);
|
||||
} else
|
||||
memset(&cw, 0, sizeof(cw));
|
||||
|
||||
xo_set_version(SOCKSTAT_XO_VERSION);
|
||||
xo_open_container("sockstat");
|
||||
xo_open_list("socket");
|
||||
if (!opt_q) {
|
||||
printf("%-*s %-*s %*s %*s %-*s %-*s %-*s",
|
||||
cw.user, "USER", cw.command, "COMMAND",
|
||||
cw.pid, "PID", cw.fd, "FD", cw.proto, "PROTO",
|
||||
cw.local_addr, "LOCAL ADDRESS",
|
||||
cw.foreign_addr,"FOREIGN ADDRESS");
|
||||
xo_emit("{T:/%-*s} {T:/%-*s} {T:/%*s} {T:/%*s} {T:/%-*s} "
|
||||
"{T:/%-*s} {T:/%-*s}", cw.user, "USER", cw.command,
|
||||
"COMMAND", cw.pid, "PID", cw.fd, "FD", cw.proto,
|
||||
"PROTO", cw.local_addr, "LOCAL ADDRESS",
|
||||
cw.foreign_addr, "FOREIGN ADDRESS");
|
||||
if (opt_A)
|
||||
printf(" %-*s", cw.pcb_kva, "PCB KVA");
|
||||
xo_emit(" {T:/%-*s}", cw.pcb_kva, "PCB KVA");
|
||||
if (opt_f)
|
||||
/* RT_MAXFIBS is 65535. */
|
||||
printf(" %*s", cw.fib, "FIB");
|
||||
xo_emit(" {T:/%*s}", cw.fib, "FIB");
|
||||
if (opt_I)
|
||||
printf(" %-*s", cw.splice_address, "SPLICE ADDRESS");
|
||||
xo_emit(" {T:/%-*s}", cw.splice_address,
|
||||
"SPLICE ADDRESS");
|
||||
if (opt_i)
|
||||
printf(" %*s", cw.inp_gencnt, "ID");
|
||||
xo_emit(" {T:/%*s}", cw.inp_gencnt, "ID");
|
||||
if (opt_U)
|
||||
printf(" %*s", cw.encaps, "ENCAPS");
|
||||
xo_emit(" {T:/%*s}", cw.encaps, "ENCAPS");
|
||||
if (opt_s) {
|
||||
printf(" %-*s", cw.path_state, "PATH STATE");
|
||||
printf(" %-*s", cw.conn_state, "CONN STATE");
|
||||
xo_emit(" {T:/%-*s}", cw.path_state, "PATH STATE");
|
||||
xo_emit(" {T:/%-*s}", cw.conn_state, "CONN STATE");
|
||||
}
|
||||
if (opt_S)
|
||||
printf(" %-*s", cw.stack, "STACK");
|
||||
xo_emit(" {T:/%-*s}", cw.stack, "STACK");
|
||||
if (opt_C)
|
||||
printf(" %-*s", cw.cc, "CC");
|
||||
printf("\n");
|
||||
xo_emit(" {T:/%-*s}", cw.cc, "CC");
|
||||
xo_emit("\n");
|
||||
}
|
||||
cap_setpassent(cappwd, 1);
|
||||
for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
|
||||
|
|
@ -1550,17 +1636,24 @@ display(void)
|
|||
s = RB_FIND(socks_t, &socks,
|
||||
&(struct sock){ .socket = xf->xf_data});
|
||||
if (s != NULL && check_ports(s)) {
|
||||
xo_open_instance("socket");
|
||||
s->shown = 1;
|
||||
if (opt_n ||
|
||||
(pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
|
||||
printf("%-*lu", cw.user, (u_long)xf->xf_uid);
|
||||
xo_emit("{:user/%-*lu}", cw.user,
|
||||
(u_long)xf->xf_uid);
|
||||
else
|
||||
printf("%-*s", cw.user, pwd->pw_name);
|
||||
printf(" %-*.*s", cw.command, cw.command,
|
||||
getprocname(xf->xf_pid));
|
||||
printf(" %*lu", cw.pid, (u_long)xf->xf_pid);
|
||||
printf(" %*d", cw.fd, xf->xf_fd);
|
||||
xo_emit("{:user/%-*s}", cw.user, pwd->pw_name);
|
||||
if (xo_get_style(NULL) == XO_STYLE_TEXT)
|
||||
xo_emit(" {:/%-*.10s}", cw.command,
|
||||
getprocname(xf->xf_pid));
|
||||
else
|
||||
xo_emit(" {:command/%-*s}", cw.command,
|
||||
getprocname(xf->xf_pid));
|
||||
xo_emit(" {:pid/%*lu}", cw.pid, (u_long)xf->xf_pid);
|
||||
xo_emit(" {:fd/%*d}", cw.fd, xf->xf_fd);
|
||||
display_sock(s, &cw, buf, bufsize);
|
||||
xo_close_instance("socket");
|
||||
}
|
||||
}
|
||||
if (opt_j >= 0)
|
||||
|
|
@ -1568,20 +1661,33 @@ display(void)
|
|||
SLIST_FOREACH(s, &nosocks, socket_list) {
|
||||
if (!check_ports(s))
|
||||
continue;
|
||||
printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??",
|
||||
cw.pid, "??", cw.fd, "??");
|
||||
xo_open_instance("socket");
|
||||
if (xo_get_style(NULL) == XO_STYLE_TEXT)
|
||||
xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}",
|
||||
cw.user, "??", cw.command, "??",
|
||||
cw.pid, "??", cw.fd, "??");
|
||||
display_sock(s, &cw, buf, bufsize);
|
||||
xo_close_instance("socket");
|
||||
}
|
||||
RB_FOREACH(s, socks_t, &socks) {
|
||||
if (s->shown)
|
||||
continue;
|
||||
if (!check_ports(s))
|
||||
continue;
|
||||
printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??",
|
||||
cw.pid, "??", cw.fd, "??");
|
||||
xo_open_instance("socket");
|
||||
if (xo_get_style(NULL) == XO_STYLE_TEXT)
|
||||
xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}",
|
||||
cw.user, "??", cw.command, "??",
|
||||
cw.pid, "??", cw.fd, "??");
|
||||
display_sock(s, &cw, buf, bufsize);
|
||||
xo_close_instance("socket");
|
||||
}
|
||||
xo_close_list("socket");
|
||||
xo_close_container("sockstat");
|
||||
if (xo_finish() < 0)
|
||||
xo_err(1, "stdout");
|
||||
free(buf);
|
||||
cap_endpwent(cappwd);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1597,7 +1703,7 @@ set_default_protos(void)
|
|||
pname = default_protos[pindex];
|
||||
prot = cap_getprotobyname(capnetdb, pname);
|
||||
if (prot == NULL)
|
||||
err(1, "cap_getprotobyname: %s", pname);
|
||||
xo_err(1, "cap_getprotobyname: %s", pname);
|
||||
protos[pindex] = prot->p_proto;
|
||||
}
|
||||
numprotos = pindex;
|
||||
|
|
@ -1643,8 +1749,10 @@ jail_getvnet(int jid)
|
|||
static void
|
||||
usage(void)
|
||||
{
|
||||
errx(1,
|
||||
"usage: sockstat [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]");
|
||||
xo_error(
|
||||
"usage: sockstat [--libxo] [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports]\n"
|
||||
" [-P protocols]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -1657,6 +1765,9 @@ main(int argc, char *argv[])
|
|||
int protos_defined = -1;
|
||||
int o, i;
|
||||
|
||||
argc = xo_parse_args(argc, argv);
|
||||
if (argc < 0)
|
||||
exit(1);
|
||||
opt_j = -1;
|
||||
while ((o = getopt(argc, argv, "46ACcfIij:Llnp:P:qSsUuvw")) != -1)
|
||||
switch (o) {
|
||||
|
|
@ -1687,7 +1798,7 @@ main(int argc, char *argv[])
|
|||
case 'j':
|
||||
opt_j = jail_getid(optarg);
|
||||
if (opt_j < 0)
|
||||
errx(1, "jail_getid: %s", jail_errmsg);
|
||||
xo_errx(1, "jail_getid: %s", jail_errmsg);
|
||||
break;
|
||||
case 'L':
|
||||
opt_L = true;
|
||||
|
|
@ -1738,10 +1849,10 @@ main(int argc, char *argv[])
|
|||
if (opt_j > 0) {
|
||||
switch (jail_getvnet(opt_j)) {
|
||||
case -1:
|
||||
errx(2, "jail_getvnet: %s", jail_errmsg);
|
||||
xo_errx(2, "jail_getvnet: %s", jail_errmsg);
|
||||
case JAIL_SYS_NEW:
|
||||
if (jail_attach(opt_j) < 0)
|
||||
err(3, "jail_attach()");
|
||||
xo_err(3, "jail_attach()");
|
||||
/* Set back to -1 for normal output in vnet jail. */
|
||||
opt_j = -1;
|
||||
break;
|
||||
|
|
@ -1752,31 +1863,31 @@ main(int argc, char *argv[])
|
|||
|
||||
capcas = cap_init();
|
||||
if (capcas == NULL)
|
||||
err(1, "Unable to contact Casper");
|
||||
xo_err(1, "Unable to contact Casper");
|
||||
if (caph_enter_casper() < 0)
|
||||
err(1, "Unable to enter capability mode");
|
||||
xo_err(1, "Unable to enter capability mode");
|
||||
capnet = cap_service_open(capcas, "system.net");
|
||||
if (capnet == NULL)
|
||||
err(1, "Unable to open system.net service");
|
||||
xo_err(1, "Unable to open system.net service");
|
||||
capnetdb = cap_service_open(capcas, "system.netdb");
|
||||
if (capnetdb == NULL)
|
||||
err(1, "Unable to open system.netdb service");
|
||||
xo_err(1, "Unable to open system.netdb service");
|
||||
capsysctl = cap_service_open(capcas, "system.sysctl");
|
||||
if (capsysctl == NULL)
|
||||
err(1, "Unable to open system.sysctl service");
|
||||
xo_err(1, "Unable to open system.sysctl service");
|
||||
cappwd = cap_service_open(capcas, "system.pwd");
|
||||
if (cappwd == NULL)
|
||||
err(1, "Unable to open system.pwd service");
|
||||
xo_err(1, "Unable to open system.pwd service");
|
||||
cap_close(capcas);
|
||||
limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME);
|
||||
if (limit == NULL)
|
||||
err(1, "Unable to init cap_net limits");
|
||||
xo_err(1, "Unable to init cap_net limits");
|
||||
if (cap_net_limit(limit) < 0)
|
||||
err(1, "Unable to apply limits");
|
||||
xo_err(1, "Unable to apply limits");
|
||||
if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0)
|
||||
err(1, "Unable to apply pwd commands limits");
|
||||
xo_err(1, "Unable to apply pwd commands limits");
|
||||
if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0)
|
||||
err(1, "Unable to apply pwd commands limits");
|
||||
xo_err(1, "Unable to apply pwd commands limits");
|
||||
|
||||
if ((!opt_4 && !opt_6) && protos_defined != -1)
|
||||
opt_4 = opt_6 = true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue