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
	 Doug MacEachern
						Doug MacEachern