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
	
	Block a user