Add SCTP support.

PR:		201585
MFC after:	3 weeks
This commit is contained in:
tuexen 2015-08-26 23:45:06 +00:00
parent ccb05b74c8
commit 4c1edcc074
2 changed files with 63 additions and 7 deletions

View File

@ -27,7 +27,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd July 14, 2015 .Dd August 27, 2015
.Dt SOCKSTAT 1 .Dt SOCKSTAT 1
.Os .Os
.Sh NAME .Sh NAME
@ -85,7 +85,7 @@ as they are defined in
.Xr protocols 5 . .Xr protocols 5 .
.It Fl s .It Fl s
Display the protocol state, if applicable. Display the protocol state, if applicable.
This is currently only implemented for TCP. This is currently only implemented for SCTP and TCP.
.It Fl u .It Fl u
Show Show
.Dv AF_LOCAL .Dv AF_LOCAL

View File

@ -332,6 +332,12 @@ gather_sctp(void)
sock->socket = xinpcb->socket; sock->socket = xinpcb->socket;
sock->proto = IPPROTO_SCTP; sock->proto = IPPROTO_SCTP;
sock->protoname = "sctp"; sock->protoname = "sctp";
if (xinpcb->flags & SCTP_PCB_FLAGS_UNBOUND)
sock->state = SCTP_CLOSED;
else if (xinpcb->maxqlen == 0)
sock->state = SCTP_BOUND;
else
sock->state = SCTP_LISTEN;
if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
sock->family = AF_INET6; sock->family = AF_INET6;
sock->vflag = INP_IPV6; sock->vflag = INP_IPV6;
@ -421,6 +427,7 @@ gather_sctp(void)
sock->socket = xinpcb->socket; sock->socket = xinpcb->socket;
sock->proto = IPPROTO_SCTP; sock->proto = IPPROTO_SCTP;
sock->protoname = "sctp"; sock->protoname = "sctp";
sock->state = (int)xstcb->state;
if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
sock->family = AF_INET6; sock->family = AF_INET6;
sock->vflag = INP_IPV6; sock->vflag = INP_IPV6;
@ -906,6 +913,46 @@ check_ports(struct sock *s)
return (0); return (0);
} }
static const char *
sctp_state(int state)
{
switch (state) {
case SCTP_CLOSED:
return "CLOSED";
break;
case SCTP_BOUND:
return "BOUND";
break;
case SCTP_LISTEN:
return "LISTEN";
break;
case SCTP_COOKIE_WAIT:
return "COOKIE_WAIT";
break;
case SCTP_COOKIE_ECHOED:
return "COOKIE_ECHOED";
break;
case SCTP_ESTABLISHED:
return "ESTABLISHED";
break;
case SCTP_SHUTDOWN_SENT:
return "SHUTDOWN_SENT";
break;
case SCTP_SHUTDOWN_RECEIVED:
return "SHUTDOWN_RECEIVED";
break;
case SCTP_SHUTDOWN_ACK_SENT:
return "SHUTDOWN_ACK_SENT";
break;
case SCTP_SHUTDOWN_PENDING:
return "SHUTDOWN_PENDING";
break;
default:
return "UNKNOWN";
break;
}
}
static void static void
displaysock(struct sock *s, int pos) displaysock(struct sock *s, int pos)
{ {
@ -975,13 +1022,22 @@ displaysock(struct sock *s, int pos)
default: default:
abort(); abort();
} }
if (first && opt_s && s->proto == IPPROTO_TCP) { if (first && opt_s &&
(s->proto == IPPROTO_SCTP || s->proto == IPPROTO_TCP)) {
while (pos < 80) while (pos < 80)
pos += xprintf(" "); pos += xprintf(" ");
if (s->state >= 0 && s->state < TCP_NSTATES) switch (s->proto) {
pos += xprintf("%s", tcpstates[s->state]); case IPPROTO_SCTP:
else pos += xprintf("%s", sctp_state(s->state));
pos += xprintf("?"); break;
case IPPROTO_TCP:
if (s->state >= 0 && s->state < TCP_NSTATES)
pos +=
xprintf("%s", tcpstates[s->state]);
else
pos += xprintf("?");
break;
}
} }
if (laddr != NULL) if (laddr != NULL)
laddr = laddr->next; laddr = laddr->next;