freebsd5 net_connection_list impl
This commit is contained in:
parent
da4605cc9f
commit
5cb9e6bfcf
|
@ -1368,9 +1368,181 @@ int sigar_net_interface_stat_get(sigar_t *sigar, const char *name,
|
|||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
#if defined(SIGAR_FREEBSD5)
|
||||
|
||||
#include <sys/socketvar.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/tcp_fsm.h>
|
||||
|
||||
static int net_connection_list_get(sigar_t *sigar,
|
||||
sigar_net_connection_list_t *connlist,
|
||||
int flags, int proto)
|
||||
{
|
||||
int type, istcp = 0;
|
||||
char *buf;
|
||||
const char *mibvar;
|
||||
struct tcpcb *tp = NULL;
|
||||
struct inpcb *inp;
|
||||
struct xinpgen *xig, *oxig;
|
||||
struct xsocket *so;
|
||||
size_t len;
|
||||
|
||||
switch (proto) {
|
||||
case IPPROTO_TCP:
|
||||
mibvar = "net.inet.tcp.pcblist";
|
||||
istcp = 1;
|
||||
type = SIGAR_NETCONN_TCP;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
mibvar = "net.inet.udp.pcblist";
|
||||
type = SIGAR_NETCONN_UDP;
|
||||
break;
|
||||
default:
|
||||
mibvar = "net.inet.raw.pcblist";
|
||||
type = SIGAR_NETCONN_RAW;
|
||||
break;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
|
||||
return errno;
|
||||
}
|
||||
if ((buf = malloc(len)) == 0) {
|
||||
return errno;
|
||||
}
|
||||
if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
|
||||
free(buf);
|
||||
return errno;
|
||||
}
|
||||
|
||||
oxig = xig = (struct xinpgen *)buf;
|
||||
for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
|
||||
xig->xig_len > sizeof(struct xinpgen);
|
||||
xig = (struct xinpgen *)((char *)xig + xig->xig_len))
|
||||
{
|
||||
if (istcp) {
|
||||
struct xtcpcb *cb = (struct xtcpcb *)xig;
|
||||
tp = &cb->xt_tp;
|
||||
inp = &cb->xt_inp;
|
||||
so = &cb->xt_socket;
|
||||
}
|
||||
else {
|
||||
struct xinpcb *cb = (struct xincb *)xig;
|
||||
inp = &cb->xi_inp;
|
||||
so = &cb->xi_socket;
|
||||
}
|
||||
|
||||
if (so->xso_protocol != proto) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inp->inp_gencnt > oxig->xig_gen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((((flags & SIGAR_NETCONN_SERVER) && so->so_qlimit) ||
|
||||
((flags & SIGAR_NETCONN_CLIENT) && !so->so_qlimit)))
|
||||
{
|
||||
sigar_net_connection_t *conn;
|
||||
|
||||
SIGAR_NET_CONNLIST_GROW(connlist);
|
||||
conn = &connlist->data[connlist->number++];
|
||||
|
||||
sigar_inet_ntoa(sigar, inp->inp_laddr.s_addr,
|
||||
conn->local_address);
|
||||
sigar_inet_ntoa(sigar, inp->inp_faddr.s_addr,
|
||||
conn->remote_address);
|
||||
conn->local_port = ntohs(inp->inp_lport);
|
||||
conn->remote_port = ntohs(inp->inp_fport);
|
||||
conn->receive_queue = so->so_rcv.sb_cc;
|
||||
conn->send_queue = so->so_snd.sb_cc;
|
||||
conn->type = type;
|
||||
|
||||
if (!istcp) {
|
||||
conn->state = SIGAR_TCP_UNKNOWN;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
int sigar_net_connection_list_get(sigar_t *sigar,
|
||||
sigar_net_connection_list_t *connlist,
|
||||
int flags)
|
||||
{
|
||||
int status;
|
||||
|
||||
sigar_net_connection_list_create(connlist);
|
||||
|
||||
if (flags & SIGAR_NETCONN_TCP) {
|
||||
status = net_connection_list_get(sigar, connlist,
|
||||
flags, IPPROTO_TCP);
|
||||
if (status != SIGAR_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
if (flags & SIGAR_NETCONN_UDP) {
|
||||
status = net_connection_list_get(sigar, connlist,
|
||||
flags, IPPROTO_UDP);
|
||||
if (status != SIGAR_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int sigar_net_connection_list_get(sigar_t *sigar,
|
||||
sigar_net_connection_list_t *connlist,
|
||||
int flags)
|
||||
{
|
||||
return SIGAR_ENOTIMPL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue