Index: lib/libprocstat/Symbol.map =================================================================== --- lib/libprocstat/Symbol.map +++ lib/libprocstat/Symbol.map @@ -6,7 +6,6 @@ procstat_freefiles; procstat_freeprocs; procstat_get_pipe_info; - procstat_get_socket_info; procstat_getfiles; procstat_getprocs; procstat_open_kvm; @@ -39,5 +38,6 @@ procstat_get_pts_info; procstat_get_sem_info; procstat_get_shm_info; + procstat_get_socket_info; procstat_get_vnode_info; }; Index: lib/libprocstat/libprocstat.h =================================================================== --- lib/libprocstat/libprocstat.h +++ lib/libprocstat/libprocstat.h @@ -157,6 +157,8 @@ struct sockaddr_storage sa_peer; /* Peer address. */ int type; char dname[32]; + unsigned int sendq; + unsigned int recvq; }; STAILQ_HEAD(filestat_list, filestat); Index: lib/libprocstat/libprocstat.c =================================================================== --- lib/libprocstat/libprocstat.c +++ lib/libprocstat/libprocstat.c @@ -1497,6 +1497,8 @@ } else sock->inp_ppcb = (uintptr_t)inpcb.inp_ppcb; + sock->sendq = s.so_snd.sb_ccc; + sock->recvq = s.so_rcv.sb_ccc; } } break; @@ -1510,6 +1512,8 @@ sock->so_rcv_sb_state = s.so_rcv.sb_state; sock->so_snd_sb_state = s.so_snd.sb_state; sock->unp_conn = (uintptr_t)unpcb.unp_conn; + sock->sendq = s.so_snd.sb_ccc; + sock->recvq = s.so_rcv.sb_ccc; } } break; @@ -1556,17 +1560,22 @@ switch(sock->dom_family) { case AF_INET: case AF_INET6: - if (sock->proto == IPPROTO_TCP) + if (sock->proto == IPPROTO_TCP) { sock->inp_ppcb = kif->kf_un.kf_sock.kf_sock_inpcb; + sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq; + sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq; + } break; case AF_UNIX: if (kif->kf_un.kf_sock.kf_sock_unpconn != 0) { - sock->so_rcv_sb_state = - kif->kf_un.kf_sock.kf_sock_rcv_sb_state; - sock->so_snd_sb_state = - kif->kf_un.kf_sock.kf_sock_snd_sb_state; - sock->unp_conn = - kif->kf_un.kf_sock.kf_sock_unpconn; + sock->so_rcv_sb_state = + kif->kf_un.kf_sock.kf_sock_rcv_sb_state; + sock->so_snd_sb_state = + kif->kf_un.kf_sock.kf_sock_snd_sb_state; + sock->unp_conn = + kif->kf_un.kf_sock.kf_sock_unpconn; + sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq; + sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq; } break; default: Index: lib/libprocstat/libprocstat_compat.c =================================================================== --- lib/libprocstat/libprocstat_compat.c +++ lib/libprocstat/libprocstat_compat.c @@ -60,12 +60,29 @@ uint16_t mode; }; +struct freebsd11_sockstat { + uint64_t inp_ppcb; + uint64_t so_addr; + uint64_t so_pcb; + uint64_t unp_conn; + int dom_family; + int proto; + int so_rcv_sb_state; + int so_snd_sb_state; + struct sockaddr_storage sa_local; /* Socket address. */ + struct sockaddr_storage sa_peer; /* Peer address. */ + int type; + char dname[32]; +}; + int freebsd11_procstat_get_pts_info(struct procstat *procstat, struct filestat *fst, struct freebsd11_ptsstat *pts, char *errbuf); int freebsd11_procstat_get_sem_info(struct procstat *procstat, struct filestat *fst, struct freebsd11_semstat *sem, char *errbuf); int freebsd11_procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, struct freebsd11_shmstat *shm, char *errbuf); +int freebsd11_procstat_get_socket_info(struct procstat *procstat, + struct filestat *fst, struct freebsd11_sockstat *sock, char *errbuf); int freebsd11_procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, struct freebsd11_vnstat *vn, char *errbuf); @@ -116,6 +133,31 @@ } int +freebsd11_procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, + struct freebsd11_sockstat *sock_compat, char *errbuf) +{ + struct sockstat sock; + int r; + + r = procstat_get_socket_info(procstat, fst, &sock, errbuf); + if (r != 0) + return (r); + sock_compat->inp_ppcb = sock.inp_ppcb; + sock_compat->so_addr = sock.so_addr; + sock_compat->so_pcb = sock.so_pcb; + sock_compat->unp_conn = sock.unp_conn; + sock_compat->dom_family = sock.dom_family; + sock_compat->proto = sock.proto; + sock_compat->so_rcv_sb_state = sock.so_rcv_sb_state; + sock_compat->so_snd_sb_state = sock.so_snd_sb_state; + sock_compat->sa_local = sock.sa_local; + sock_compat->sa_peer = sock.sa_peer; + sock_compat->type = sock.type; + memcpy(sock_compat->dname, sock.dname, sizeof(sock.dname)); + return (0); +} + +int freebsd11_procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, struct freebsd11_vnstat *vn_compat, char *errbuf) { @@ -138,6 +180,8 @@ } __sym_compat(procstat_get_pts_info, freebsd11_procstat_get_pts_info, FBSD_1.2); +__sym_compat(procstat_get_socket_info, freebsd11_procstat_get_socket_info, + FBSD_1.2); __sym_compat(procstat_get_vnode_info, freebsd11_procstat_get_vnode_info, FBSD_1.2); __sym_compat(procstat_get_sem_info, freebsd11_procstat_get_sem_info, FBSD_1.3); Index: sys/kern/sys_socket.c =================================================================== --- sys/kern/sys_socket.c +++ sys/kern/sys_socket.c @@ -359,6 +359,10 @@ inpcb = (struct inpcb *)(so->so_pcb); kif->kf_un.kf_sock.kf_sock_inpcb = (uintptr_t)inpcb->inp_ppcb; + kif->kf_un.kf_sock.kf_sock_sendq = + sbused(&so->so_snd); + kif->kf_un.kf_sock.kf_sock_recvq = + sbused(&so->so_rcv); } } break; @@ -372,6 +376,10 @@ so->so_rcv.sb_state; kif->kf_un.kf_sock.kf_sock_snd_sb_state = so->so_snd.sb_state; + kif->kf_un.kf_sock.kf_sock_sendq = + sbused(&so->so_snd); + kif->kf_un.kf_sock.kf_sock_recvq = + sbused(&so->so_rcv); } } break; Index: sys/sys/user.h =================================================================== --- sys/sys/user.h +++ sys/sys/user.h @@ -344,7 +344,8 @@ int64_t kf_offset; /* Seek location. */ union { struct { - uint32_t kf_spareint; + /* Sendq size */ + uint32_t kf_sock_sendq; /* Socket domain. */ int kf_sock_domain0; /* Socket type. */ @@ -365,8 +366,8 @@ uint16_t kf_sock_snd_sb_state; /* Receive buffer state. */ uint16_t kf_sock_rcv_sb_state; - /* Round to 64 bit alignment. */ - uint32_t kf_sock_pad0; + /* Recvq size. */ + uint32_t kf_sock_recvq; } kf_sock; struct { /* Vnode type. */ Index: usr.bin/procstat/procstat_files.c =================================================================== --- usr.bin/procstat/procstat_files.c +++ usr.bin/procstat/procstat_files.c @@ -534,6 +534,12 @@ xo_emit("{:protocol/%-3s/%s} ", protocol_to_string(sock.dom_family, sock.type, sock.proto)); + if (sock.proto == IPPROTO_TCP || + sock.proto == IPPROTO_SCTP || + sock.type == SOCK_STREAM) { + xo_emit("{:sendq/%u} ", sock.sendq); + xo_emit("{:recvq/%u} ", sock.recvq); + } /* * While generally we like to print two addresses, * local and peer, for sockets, it turns out to be