OpenBSD net_connection impl
This commit is contained in:
parent
eccfefcb6b
commit
a941cdc3ba
|
@ -157,8 +157,9 @@ static int get_koffsets(sigar_t *sigar)
|
||||||
struct nlist klist[] = {
|
struct nlist klist[] = {
|
||||||
{ "_cp_time" },
|
{ "_cp_time" },
|
||||||
{ "_cnt" },
|
{ "_cnt" },
|
||||||
#if !defined(TCPCTL_STATS) && defined(__OpenBSD__)
|
#if defined(__OpenBSD__)
|
||||||
{ "_tcpstat" },
|
{ "_tcpstat" },
|
||||||
|
{ "_tcbtable" },
|
||||||
#endif
|
#endif
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
@ -2381,7 +2382,133 @@ int sigar_net_interface_stat_get(sigar_t *sigar, const char *name,
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __OpenBSD__
|
static int net_connection_state_get(int state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case TCPS_CLOSED:
|
||||||
|
return SIGAR_TCP_CLOSE;
|
||||||
|
case TCPS_LISTEN:
|
||||||
|
return SIGAR_TCP_LISTEN;
|
||||||
|
case TCPS_SYN_SENT:
|
||||||
|
return SIGAR_TCP_SYN_SENT;
|
||||||
|
case TCPS_SYN_RECEIVED:
|
||||||
|
return SIGAR_TCP_SYN_RECV;
|
||||||
|
case TCPS_ESTABLISHED:
|
||||||
|
return SIGAR_TCP_ESTABLISHED;
|
||||||
|
case TCPS_CLOSE_WAIT:
|
||||||
|
return SIGAR_TCP_CLOSE_WAIT;
|
||||||
|
case TCPS_FIN_WAIT_1:
|
||||||
|
return SIGAR_TCP_FIN_WAIT1;
|
||||||
|
case TCPS_CLOSING:
|
||||||
|
return SIGAR_TCP_CLOSING;
|
||||||
|
case TCPS_LAST_ACK:
|
||||||
|
return SIGAR_TCP_LAST_ACK;
|
||||||
|
case TCPS_FIN_WAIT_2:
|
||||||
|
return SIGAR_TCP_FIN_WAIT2;
|
||||||
|
case TCPS_TIME_WAIT:
|
||||||
|
return SIGAR_TCP_TIME_WAIT;
|
||||||
|
default:
|
||||||
|
return SIGAR_TCP_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
static int net_connection_get(sigar_net_connection_walker_t *walker, int proto)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int istcp = 0, type;
|
||||||
|
int flags = walker->flags;
|
||||||
|
struct inpcbtable table;
|
||||||
|
struct inpcb *head, *next, *prev;
|
||||||
|
sigar_t *sigar = walker->sigar;
|
||||||
|
u_long offset;
|
||||||
|
|
||||||
|
switch (proto) {
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
offset = sigar->koffsets[KOFFSET_TCBTABLE];
|
||||||
|
istcp = 1;
|
||||||
|
type = SIGAR_NETCONN_TCP;
|
||||||
|
break;
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
default:
|
||||||
|
return SIGAR_ENOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status = kread(sigar, &table, sizeof(table), offset);
|
||||||
|
|
||||||
|
if (status != SIGAR_OK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = head =
|
||||||
|
(struct inpcb *)&CIRCLEQ_FIRST(&((struct inpcbtable *)offset)->inpt_queue);
|
||||||
|
|
||||||
|
next = CIRCLEQ_FIRST(&table.inpt_queue);
|
||||||
|
|
||||||
|
while (next != head) {
|
||||||
|
struct inpcb inpcb;
|
||||||
|
struct tcpcb tcpcb;
|
||||||
|
struct socket socket;
|
||||||
|
|
||||||
|
status = kread(sigar, &inpcb, sizeof(inpcb), (long)next);
|
||||||
|
prev = next;
|
||||||
|
next = CIRCLEQ_NEXT(&inpcb, inp_queue);
|
||||||
|
|
||||||
|
kread(sigar, &socket, sizeof(socket), (u_long)inpcb.inp_socket);
|
||||||
|
|
||||||
|
if ((((flags & SIGAR_NETCONN_SERVER) && socket.so_qlimit) ||
|
||||||
|
((flags & SIGAR_NETCONN_CLIENT) && !socket.so_qlimit)))
|
||||||
|
{
|
||||||
|
sigar_net_connection_t conn;
|
||||||
|
|
||||||
|
SIGAR_ZERO(&conn);
|
||||||
|
|
||||||
|
if (istcp) {
|
||||||
|
kread(sigar, &tcpcb, sizeof(tcpcb), (u_long)inpcb.inp_ppcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inpcb.inp_flags & INP_IPV6) {
|
||||||
|
sigar_net_address6_set(conn.local_address,
|
||||||
|
&inpcb.inp_laddr6.s6_addr);
|
||||||
|
|
||||||
|
sigar_net_address6_set(conn.remote_address,
|
||||||
|
&inpcb.inp_faddr6.s6_addr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sigar_net_address_set(conn.local_address,
|
||||||
|
inpcb.inp_laddr.s_addr);
|
||||||
|
|
||||||
|
sigar_net_address_set(conn.remote_address,
|
||||||
|
inpcb.inp_faddr.s_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.local_port = ntohs(inpcb.inp_lport);
|
||||||
|
conn.remote_port = ntohs(inpcb.inp_fport);
|
||||||
|
conn.receive_queue = socket.so_rcv.sb_cc;
|
||||||
|
conn.send_queue = socket.so_snd.sb_cc;
|
||||||
|
conn.uid = socket.so_pgid;
|
||||||
|
conn.type = type;
|
||||||
|
|
||||||
|
if (!istcp) {
|
||||||
|
conn.state = SIGAR_TCP_UNKNOWN;
|
||||||
|
if (walker->add_connection(walker, &conn) != SIGAR_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.state = net_connection_state_get(tcpcb.t_state);
|
||||||
|
|
||||||
|
if (walker->add_connection(walker, &conn) != SIGAR_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
#else
|
||||||
static int net_connection_get(sigar_net_connection_walker_t *walker, int proto)
|
static int net_connection_get(sigar_net_connection_walker_t *walker, int proto)
|
||||||
{
|
{
|
||||||
int flags = walker->flags;
|
int flags = walker->flags;
|
||||||
|
@ -2484,44 +2611,7 @@ static int net_connection_get(sigar_net_connection_walker_t *walker, int proto)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tp->t_state) {
|
conn.state = net_connection_state_get(tp->t_state);
|
||||||
case TCPS_CLOSED:
|
|
||||||
conn.state = SIGAR_TCP_CLOSE;
|
|
||||||
break;
|
|
||||||
case TCPS_LISTEN:
|
|
||||||
conn.state = SIGAR_TCP_LISTEN;
|
|
||||||
break;
|
|
||||||
case TCPS_SYN_SENT:
|
|
||||||
conn.state = SIGAR_TCP_SYN_SENT;
|
|
||||||
break;
|
|
||||||
case TCPS_SYN_RECEIVED:
|
|
||||||
conn.state = SIGAR_TCP_SYN_RECV;
|
|
||||||
break;
|
|
||||||
case TCPS_ESTABLISHED:
|
|
||||||
conn.state = SIGAR_TCP_ESTABLISHED;
|
|
||||||
break;
|
|
||||||
case TCPS_CLOSE_WAIT:
|
|
||||||
conn.state = SIGAR_TCP_CLOSE_WAIT;
|
|
||||||
break;
|
|
||||||
case TCPS_FIN_WAIT_1:
|
|
||||||
conn.state = SIGAR_TCP_FIN_WAIT1;
|
|
||||||
break;
|
|
||||||
case TCPS_CLOSING:
|
|
||||||
conn.state = SIGAR_TCP_CLOSING;
|
|
||||||
break;
|
|
||||||
case TCPS_LAST_ACK:
|
|
||||||
conn.state = SIGAR_TCP_LAST_ACK;
|
|
||||||
break;
|
|
||||||
case TCPS_FIN_WAIT_2:
|
|
||||||
conn.state = SIGAR_TCP_FIN_WAIT2;
|
|
||||||
break;
|
|
||||||
case TCPS_TIME_WAIT:
|
|
||||||
conn.state = SIGAR_TCP_TIME_WAIT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
conn.state = SIGAR_TCP_UNKNOWN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walker->add_connection(walker, &conn) != SIGAR_OK) {
|
if (walker->add_connection(walker, &conn) != SIGAR_OK) {
|
||||||
break;
|
break;
|
||||||
|
@ -2533,6 +2623,7 @@ static int net_connection_get(sigar_net_connection_walker_t *walker, int proto)
|
||||||
|
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int sigar_net_connection_walk(sigar_net_connection_walker_t *walker)
|
int sigar_net_connection_walk(sigar_net_connection_walker_t *walker)
|
||||||
{
|
{
|
||||||
|
@ -2554,12 +2645,6 @@ int sigar_net_connection_walk(sigar_net_connection_walker_t *walker)
|
||||||
|
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
int sigar_net_connection_walk(sigar_net_connection_walker_t *walker)
|
|
||||||
{
|
|
||||||
return SIGAR_ENOTIMPL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SIGAR_DECLARE(int)
|
SIGAR_DECLARE(int)
|
||||||
sigar_tcp_get(sigar_t *sigar,
|
sigar_tcp_get(sigar_t *sigar,
|
||||||
|
|
|
@ -33,6 +33,7 @@ enum {
|
||||||
KOFFSET_VMMETER,
|
KOFFSET_VMMETER,
|
||||||
#if defined(__OpenBSD__)
|
#if defined(__OpenBSD__)
|
||||||
KOFFSET_TCPSTAT,
|
KOFFSET_TCPSTAT,
|
||||||
|
KOFFSET_TCBTABLE,
|
||||||
#endif
|
#endif
|
||||||
KOFFSET_MAX
|
KOFFSET_MAX
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue