169921123SKonstantin Belousov /*-
269921123SKonstantin Belousov  * Copyright (c) 2014 Gleb Kurtsou <gleb@FreeBSD.org>
369921123SKonstantin Belousov  * All rights reserved.
469921123SKonstantin Belousov  *
569921123SKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
669921123SKonstantin Belousov  * modification, are permitted provided that the following conditions
769921123SKonstantin Belousov  * are met:
869921123SKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
969921123SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
1069921123SKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
1169921123SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
1269921123SKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
1369921123SKonstantin Belousov  *
1469921123SKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1569921123SKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1669921123SKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1769921123SKonstantin Belousov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1869921123SKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1969921123SKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2069921123SKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2169921123SKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2269921123SKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2369921123SKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2469921123SKonstantin Belousov  * SUCH DAMAGE.
2569921123SKonstantin Belousov  */
2669921123SKonstantin Belousov 
2769921123SKonstantin Belousov #include <sys/param.h>
2869921123SKonstantin Belousov #include <sys/user.h>
2969921123SKonstantin Belousov #include <sys/socket.h>
3069921123SKonstantin Belousov #include <string.h>
3169921123SKonstantin Belousov 
3269921123SKonstantin Belousov #include "libprocstat.h"
3369921123SKonstantin Belousov 
34e5ac3049SKonstantin Belousov #define	SPECNAMELEN_COMPAT12	63
35e5ac3049SKonstantin Belousov 
3669921123SKonstantin Belousov struct freebsd11_ptsstat {
3769921123SKonstantin Belousov 	uint32_t	dev;
38e5ac3049SKonstantin Belousov 	char		devname[SPECNAMELEN_COMPAT12 + 1];
3969921123SKonstantin Belousov };
4069921123SKonstantin Belousov 
4169921123SKonstantin Belousov struct freebsd11_vnstat {
4269921123SKonstantin Belousov 	uint64_t	vn_fileid;
4369921123SKonstantin Belousov 	uint64_t	vn_size;
4469921123SKonstantin Belousov 	char		*vn_mntdir;
4569921123SKonstantin Belousov 	uint32_t	vn_dev;
4669921123SKonstantin Belousov 	uint32_t	vn_fsid;
4769921123SKonstantin Belousov 	int		vn_type;
4869921123SKonstantin Belousov 	uint16_t	vn_mode;
49e5ac3049SKonstantin Belousov 	char		vn_devname[SPECNAMELEN_COMPAT12 + 1];
5069921123SKonstantin Belousov };
5169921123SKonstantin Belousov struct freebsd11_semstat {
5269921123SKonstantin Belousov 	uint32_t	value;
5369921123SKonstantin Belousov 	uint16_t	mode;
5469921123SKonstantin Belousov };
5569921123SKonstantin Belousov struct freebsd11_shmstat {
5669921123SKonstantin Belousov 	uint64_t	size;
5769921123SKonstantin Belousov 	uint16_t	mode;
5869921123SKonstantin Belousov };
5969921123SKonstantin Belousov 
6095b97895SConrad Meyer struct freebsd11_sockstat {
6195b97895SConrad Meyer 	uint64_t	inp_ppcb;
6295b97895SConrad Meyer 	uint64_t	so_addr;
6395b97895SConrad Meyer 	uint64_t	so_pcb;
6495b97895SConrad Meyer 	uint64_t	unp_conn;
6595b97895SConrad Meyer 	int		dom_family;
6695b97895SConrad Meyer 	int		proto;
6795b97895SConrad Meyer 	int		so_rcv_sb_state;
6895b97895SConrad Meyer 	int		so_snd_sb_state;
6995b97895SConrad Meyer 	struct sockaddr_storage	sa_local;	/* Socket address. */
7095b97895SConrad Meyer 	struct sockaddr_storage	sa_peer;	/* Peer address. */
7195b97895SConrad Meyer 	int		type;
7295b97895SConrad Meyer 	char		dname[32];
7395b97895SConrad Meyer };
7495b97895SConrad Meyer 
75e5ac3049SKonstantin Belousov struct freebsd12_vnstat {
76e5ac3049SKonstantin Belousov 	uint64_t	vn_fileid;
77e5ac3049SKonstantin Belousov 	uint64_t	vn_size;
78e5ac3049SKonstantin Belousov 	uint64_t	vn_dev;
79e5ac3049SKonstantin Belousov 	uint64_t	vn_fsid;
80e5ac3049SKonstantin Belousov 	char		*vn_mntdir;
81e5ac3049SKonstantin Belousov 	int		vn_type;
82e5ac3049SKonstantin Belousov 	uint16_t	vn_mode;
83e5ac3049SKonstantin Belousov 	char		vn_devname[SPECNAMELEN_COMPAT12 + 1];
84e5ac3049SKonstantin Belousov };
85e5ac3049SKonstantin Belousov struct freebsd12_ptsstat {
86e5ac3049SKonstantin Belousov 	uint64_t	dev;
87e5ac3049SKonstantin Belousov 	char		devname[SPECNAMELEN_COMPAT12 + 1];
88e5ac3049SKonstantin Belousov };
89e5ac3049SKonstantin Belousov 
9069921123SKonstantin Belousov int	freebsd11_procstat_get_pts_info(struct procstat *procstat,
9169921123SKonstantin Belousov     struct filestat *fst, struct freebsd11_ptsstat *pts, char *errbuf);
92e5ac3049SKonstantin Belousov int	freebsd12_procstat_get_pts_info(struct procstat *procstat,
93e5ac3049SKonstantin Belousov     struct filestat *fst, struct freebsd12_ptsstat *pts_compat, char *errbuf);
9469921123SKonstantin Belousov int	freebsd11_procstat_get_sem_info(struct procstat *procstat,
9569921123SKonstantin Belousov     struct filestat *fst, struct freebsd11_semstat *sem, char *errbuf);
9669921123SKonstantin Belousov int	freebsd11_procstat_get_shm_info(struct procstat *procstat,
9769921123SKonstantin Belousov     struct filestat *fst, struct freebsd11_shmstat *shm, char *errbuf);
9895b97895SConrad Meyer int	freebsd11_procstat_get_socket_info(struct procstat *procstat,
9995b97895SConrad Meyer     struct filestat *fst, struct freebsd11_sockstat *sock, char *errbuf);
10069921123SKonstantin Belousov int	freebsd11_procstat_get_vnode_info(struct procstat *procstat,
10169921123SKonstantin Belousov     struct filestat *fst, struct freebsd11_vnstat *vn, char *errbuf);
102e5ac3049SKonstantin Belousov int	freebsd12_procstat_get_vnode_info(struct procstat *procstat,
103e5ac3049SKonstantin Belousov     struct filestat *fst, struct freebsd12_vnstat *vn_compat, char *errbuf);
104e5ac3049SKonstantin Belousov 
105e5ac3049SKonstantin Belousov static const char trunc_name[] = "<TRUNCATED>";
10669921123SKonstantin Belousov 
10769921123SKonstantin Belousov int
freebsd11_procstat_get_pts_info(struct procstat * procstat,struct filestat * fst,struct freebsd11_ptsstat * pts_compat,char * errbuf)10869921123SKonstantin Belousov freebsd11_procstat_get_pts_info(struct procstat *procstat,
10969921123SKonstantin Belousov     struct filestat *fst, struct freebsd11_ptsstat *pts_compat, char *errbuf)
11069921123SKonstantin Belousov {
11169921123SKonstantin Belousov 	struct ptsstat pts;
11269921123SKonstantin Belousov 	int r;
11369921123SKonstantin Belousov 
11469921123SKonstantin Belousov 	r = procstat_get_pts_info(procstat, fst, &pts, errbuf);
11569921123SKonstantin Belousov 	if (r != 0)
11669921123SKonstantin Belousov 		return (r);
11769921123SKonstantin Belousov 	pts_compat->dev = pts.dev;
118e5ac3049SKonstantin Belousov 	if (strlen(pts.devname) >= sizeof(pts_compat->devname))
119e5ac3049SKonstantin Belousov 		strcpy(pts_compat->devname, trunc_name);
120e5ac3049SKonstantin Belousov 	else
121e5ac3049SKonstantin Belousov 		memcpy(pts_compat->devname, pts.devname,
122e5ac3049SKonstantin Belousov 		    sizeof(pts_compat->devname));
123e5ac3049SKonstantin Belousov 	return (0);
124e5ac3049SKonstantin Belousov }
125e5ac3049SKonstantin Belousov 
126e5ac3049SKonstantin Belousov int
freebsd12_procstat_get_pts_info(struct procstat * procstat,struct filestat * fst,struct freebsd12_ptsstat * pts_compat,char * errbuf)127e5ac3049SKonstantin Belousov freebsd12_procstat_get_pts_info(struct procstat *procstat,
128e5ac3049SKonstantin Belousov     struct filestat *fst, struct freebsd12_ptsstat *pts_compat, char *errbuf)
129e5ac3049SKonstantin Belousov {
130e5ac3049SKonstantin Belousov 	struct ptsstat pts;
131e5ac3049SKonstantin Belousov 	int r;
132e5ac3049SKonstantin Belousov 
133e5ac3049SKonstantin Belousov 	r = procstat_get_pts_info(procstat, fst, &pts, errbuf);
134e5ac3049SKonstantin Belousov 	if (r != 0)
135e5ac3049SKonstantin Belousov 		return (r);
136e5ac3049SKonstantin Belousov 	pts_compat->dev = pts.dev;
137e5ac3049SKonstantin Belousov 	if (strlen(pts.devname) >= sizeof(pts_compat->devname))
138e5ac3049SKonstantin Belousov 		strcpy(pts_compat->devname, trunc_name);
139e5ac3049SKonstantin Belousov 	else
14069921123SKonstantin Belousov 		memcpy(pts_compat->devname, pts.devname,
14169921123SKonstantin Belousov 		    sizeof(pts_compat->devname));
14269921123SKonstantin Belousov 	return (0);
14369921123SKonstantin Belousov }
14469921123SKonstantin Belousov 
14569921123SKonstantin Belousov int
freebsd11_procstat_get_sem_info(struct procstat * procstat,struct filestat * fst,struct freebsd11_semstat * sem_compat,char * errbuf)14669921123SKonstantin Belousov freebsd11_procstat_get_sem_info(struct procstat *procstat,
14769921123SKonstantin Belousov     struct filestat *fst, struct freebsd11_semstat *sem_compat, char *errbuf)
14869921123SKonstantin Belousov {
14969921123SKonstantin Belousov 	struct semstat sem;
15069921123SKonstantin Belousov 	int r;
15169921123SKonstantin Belousov 
15269921123SKonstantin Belousov 	r = procstat_get_sem_info(procstat, fst, &sem, errbuf);
15369921123SKonstantin Belousov 	if (r != 0)
15469921123SKonstantin Belousov 		return (r);
15569921123SKonstantin Belousov 	sem_compat->value = sem.value;
15669921123SKonstantin Belousov 	sem_compat->mode = sem.mode;
15769921123SKonstantin Belousov 	return (0);
15869921123SKonstantin Belousov }
15969921123SKonstantin Belousov 
16069921123SKonstantin Belousov int
freebsd11_procstat_get_shm_info(struct procstat * procstat,struct filestat * fst,struct freebsd11_shmstat * shm_compat,char * errbuf)16169921123SKonstantin Belousov freebsd11_procstat_get_shm_info(struct procstat *procstat,
16269921123SKonstantin Belousov     struct filestat *fst, struct freebsd11_shmstat *shm_compat, char *errbuf)
16369921123SKonstantin Belousov {
16469921123SKonstantin Belousov 	struct shmstat shm;
16569921123SKonstantin Belousov 	int r;
16669921123SKonstantin Belousov 
16769921123SKonstantin Belousov 	r = procstat_get_shm_info(procstat, fst, &shm, errbuf);
16869921123SKonstantin Belousov 	if (r != 0)
16969921123SKonstantin Belousov 		return (r);
17069921123SKonstantin Belousov 	shm_compat->size = shm.size;
17169921123SKonstantin Belousov 	shm_compat->mode = shm.mode;
17269921123SKonstantin Belousov 	return (0);
17369921123SKonstantin Belousov }
17469921123SKonstantin Belousov 
17569921123SKonstantin Belousov int
freebsd11_procstat_get_socket_info(struct procstat * procstat,struct filestat * fst,struct freebsd11_sockstat * sock_compat,char * errbuf)17695b97895SConrad Meyer freebsd11_procstat_get_socket_info(struct procstat *procstat, struct filestat *fst,
17795b97895SConrad Meyer     struct freebsd11_sockstat *sock_compat, char *errbuf)
17895b97895SConrad Meyer {
17995b97895SConrad Meyer 	struct sockstat sock;
18095b97895SConrad Meyer 	int r;
18195b97895SConrad Meyer 
18295b97895SConrad Meyer 	r = procstat_get_socket_info(procstat, fst, &sock, errbuf);
18395b97895SConrad Meyer 	if (r != 0)
18495b97895SConrad Meyer 		return (r);
1851a8d1764SGleb Smirnoff 	sock_compat->inp_ppcb = sock.so_pcb;
18695b97895SConrad Meyer 	sock_compat->so_addr = sock.so_addr;
18795b97895SConrad Meyer 	sock_compat->so_pcb = sock.so_pcb;
18895b97895SConrad Meyer 	sock_compat->unp_conn = sock.unp_conn;
18995b97895SConrad Meyer 	sock_compat->dom_family = sock.dom_family;
19095b97895SConrad Meyer 	sock_compat->proto = sock.proto;
19195b97895SConrad Meyer 	sock_compat->so_rcv_sb_state = sock.so_rcv_sb_state;
19295b97895SConrad Meyer 	sock_compat->so_snd_sb_state = sock.so_snd_sb_state;
19395b97895SConrad Meyer 	sock_compat->sa_local = sock.sa_local;
19495b97895SConrad Meyer 	sock_compat->sa_peer = sock.sa_peer;
19595b97895SConrad Meyer 	sock_compat->type = sock.type;
19695b97895SConrad Meyer 	memcpy(sock_compat->dname, sock.dname, sizeof(sock.dname));
19795b97895SConrad Meyer 	return (0);
19895b97895SConrad Meyer }
19995b97895SConrad Meyer 
20095b97895SConrad Meyer int
freebsd11_procstat_get_vnode_info(struct procstat * procstat,struct filestat * fst,struct freebsd11_vnstat * vn_compat,char * errbuf)20169921123SKonstantin Belousov freebsd11_procstat_get_vnode_info(struct procstat *procstat,
20269921123SKonstantin Belousov     struct filestat *fst, struct freebsd11_vnstat *vn_compat, char *errbuf)
20369921123SKonstantin Belousov {
20469921123SKonstantin Belousov 	struct vnstat vn;
20569921123SKonstantin Belousov 	int r;
20669921123SKonstantin Belousov 
20769921123SKonstantin Belousov 	r = procstat_get_vnode_info(procstat, fst, &vn, errbuf);
20869921123SKonstantin Belousov 	if (r != 0)
20969921123SKonstantin Belousov 		return (r);
21069921123SKonstantin Belousov 	vn_compat->vn_fileid = vn.vn_fileid;
21169921123SKonstantin Belousov 	vn_compat->vn_size = vn.vn_size;
21269921123SKonstantin Belousov 	vn_compat->vn_mntdir = vn.vn_mntdir;
21369921123SKonstantin Belousov 	vn_compat->vn_dev = vn.vn_dev;
21469921123SKonstantin Belousov 	vn_compat->vn_fsid = vn.vn_fsid;
21569921123SKonstantin Belousov 	vn_compat->vn_type = vn.vn_type;
21669921123SKonstantin Belousov 	vn_compat->vn_mode = vn.vn_mode;
217e5ac3049SKonstantin Belousov 	if (strlen(vn.vn_devname) >= sizeof(vn_compat->vn_devname))
218e5ac3049SKonstantin Belousov 		strcpy(vn_compat->vn_devname, trunc_name);
219e5ac3049SKonstantin Belousov 	else
220e5ac3049SKonstantin Belousov 		memcpy(vn_compat->vn_devname, vn.vn_devname,
221e5ac3049SKonstantin Belousov 		    sizeof(vn_compat->vn_devname));
222e5ac3049SKonstantin Belousov 	return (0);
223e5ac3049SKonstantin Belousov }
224e5ac3049SKonstantin Belousov 
225e5ac3049SKonstantin Belousov int
freebsd12_procstat_get_vnode_info(struct procstat * procstat,struct filestat * fst,struct freebsd12_vnstat * vn_compat,char * errbuf)226e5ac3049SKonstantin Belousov freebsd12_procstat_get_vnode_info(struct procstat *procstat,
227e5ac3049SKonstantin Belousov     struct filestat *fst, struct freebsd12_vnstat *vn_compat, char *errbuf)
228e5ac3049SKonstantin Belousov {
229e5ac3049SKonstantin Belousov 	struct vnstat vn;
230e5ac3049SKonstantin Belousov 	int r;
231e5ac3049SKonstantin Belousov 
232e5ac3049SKonstantin Belousov 	r = procstat_get_vnode_info(procstat, fst, &vn, errbuf);
233e5ac3049SKonstantin Belousov 	if (r != 0)
234e5ac3049SKonstantin Belousov 		return (r);
235e5ac3049SKonstantin Belousov 	vn_compat->vn_fileid = vn.vn_fileid;
236e5ac3049SKonstantin Belousov 	vn_compat->vn_size = vn.vn_size;
237e5ac3049SKonstantin Belousov 	vn_compat->vn_mntdir = vn.vn_mntdir;
238e5ac3049SKonstantin Belousov 	vn_compat->vn_dev = vn.vn_dev;
239e5ac3049SKonstantin Belousov 	vn_compat->vn_fsid = vn.vn_fsid;
240e5ac3049SKonstantin Belousov 	vn_compat->vn_type = vn.vn_type;
241e5ac3049SKonstantin Belousov 	vn_compat->vn_mode = vn.vn_mode;
242e5ac3049SKonstantin Belousov 	if (strlen(vn.vn_devname) >= sizeof(vn_compat->vn_devname))
243e5ac3049SKonstantin Belousov 		strcpy(vn_compat->vn_devname, trunc_name);
244e5ac3049SKonstantin Belousov 	else
24569921123SKonstantin Belousov 		memcpy(vn_compat->vn_devname, vn.vn_devname,
24669921123SKonstantin Belousov 		    sizeof(vn_compat->vn_devname));
24769921123SKonstantin Belousov 	return (0);
24869921123SKonstantin Belousov }
24969921123SKonstantin Belousov 
25069921123SKonstantin Belousov __sym_compat(procstat_get_pts_info, freebsd11_procstat_get_pts_info, FBSD_1.2);
25195b97895SConrad Meyer __sym_compat(procstat_get_socket_info, freebsd11_procstat_get_socket_info,
25295b97895SConrad Meyer     FBSD_1.2);
25369921123SKonstantin Belousov __sym_compat(procstat_get_vnode_info, freebsd11_procstat_get_vnode_info,
25469921123SKonstantin Belousov     FBSD_1.2);
25569921123SKonstantin Belousov __sym_compat(procstat_get_sem_info, freebsd11_procstat_get_sem_info, FBSD_1.3);
25669921123SKonstantin Belousov __sym_compat(procstat_get_shm_info, freebsd11_procstat_get_shm_info, FBSD_1.3);
257e5ac3049SKonstantin Belousov __sym_compat(procstat_get_pts_info, freebsd12_procstat_get_pts_info, FBSD_1.5);
258e5ac3049SKonstantin Belousov __sym_compat(procstat_get_vnode_info, freebsd12_procstat_get_vnode_info,
259e5ac3049SKonstantin Belousov     FBSD_1.5);
260