1 /*- 2 * Copyright (c) 2014 Gleb Kurtsou <gleb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/user.h> 32 #include <sys/socket.h> 33 #include <string.h> 34 35 #include "libprocstat.h" 36 37 #define SPECNAMELEN_COMPAT12 63 38 39 struct freebsd11_ptsstat { 40 uint32_t dev; 41 char devname[SPECNAMELEN_COMPAT12 + 1]; 42 }; 43 44 struct freebsd11_vnstat { 45 uint64_t vn_fileid; 46 uint64_t vn_size; 47 char *vn_mntdir; 48 uint32_t vn_dev; 49 uint32_t vn_fsid; 50 int vn_type; 51 uint16_t vn_mode; 52 char vn_devname[SPECNAMELEN_COMPAT12 + 1]; 53 }; 54 struct freebsd11_semstat { 55 uint32_t value; 56 uint16_t mode; 57 }; 58 struct freebsd11_shmstat { 59 uint64_t size; 60 uint16_t mode; 61 }; 62 63 struct freebsd11_sockstat { 64 uint64_t inp_ppcb; 65 uint64_t so_addr; 66 uint64_t so_pcb; 67 uint64_t unp_conn; 68 int dom_family; 69 int proto; 70 int so_rcv_sb_state; 71 int so_snd_sb_state; 72 struct sockaddr_storage sa_local; /* Socket address. */ 73 struct sockaddr_storage sa_peer; /* Peer address. */ 74 int type; 75 char dname[32]; 76 }; 77 78 struct freebsd12_vnstat { 79 uint64_t vn_fileid; 80 uint64_t vn_size; 81 uint64_t vn_dev; 82 uint64_t vn_fsid; 83 char *vn_mntdir; 84 int vn_type; 85 uint16_t vn_mode; 86 char vn_devname[SPECNAMELEN_COMPAT12 + 1]; 87 }; 88 struct freebsd12_ptsstat { 89 uint64_t dev; 90 char devname[SPECNAMELEN_COMPAT12 + 1]; 91 }; 92 93 int freebsd11_procstat_get_pts_info(struct procstat *procstat, 94 struct filestat *fst, struct freebsd11_ptsstat *pts, char *errbuf); 95 int freebsd12_procstat_get_pts_info(struct procstat *procstat, 96 struct filestat *fst, struct freebsd12_ptsstat *pts_compat, char *errbuf); 97 int freebsd11_procstat_get_sem_info(struct procstat *procstat, 98 struct filestat *fst, struct freebsd11_semstat *sem, char *errbuf); 99 int freebsd11_procstat_get_shm_info(struct procstat *procstat, 100 struct filestat *fst, struct freebsd11_shmstat *shm, char *errbuf); 101 int freebsd11_procstat_get_socket_info(struct procstat *procstat, 102 struct filestat *fst, struct freebsd11_sockstat *sock, char *errbuf); 103 int freebsd11_procstat_get_vnode_info(struct procstat *procstat, 104 struct filestat *fst, struct freebsd11_vnstat *vn, char *errbuf); 105 int freebsd12_procstat_get_vnode_info(struct procstat *procstat, 106 struct filestat *fst, struct freebsd12_vnstat *vn_compat, char *errbuf); 107 108 static const char trunc_name[] = "<TRUNCATED>"; 109 110 int 111 freebsd11_procstat_get_pts_info(struct procstat *procstat, 112 struct filestat *fst, struct freebsd11_ptsstat *pts_compat, char *errbuf) 113 { 114 struct ptsstat pts; 115 int r; 116 117 r = procstat_get_pts_info(procstat, fst, &pts, errbuf); 118 if (r != 0) 119 return (r); 120 pts_compat->dev = pts.dev; 121 if (strlen(pts.devname) >= sizeof(pts_compat->devname)) 122 strcpy(pts_compat->devname, trunc_name); 123 else 124 memcpy(pts_compat->devname, pts.devname, 125 sizeof(pts_compat->devname)); 126 return (0); 127 } 128 129 int 130 freebsd12_procstat_get_pts_info(struct procstat *procstat, 131 struct filestat *fst, struct freebsd12_ptsstat *pts_compat, char *errbuf) 132 { 133 struct ptsstat pts; 134 int r; 135 136 r = procstat_get_pts_info(procstat, fst, &pts, errbuf); 137 if (r != 0) 138 return (r); 139 pts_compat->dev = pts.dev; 140 if (strlen(pts.devname) >= sizeof(pts_compat->devname)) 141 strcpy(pts_compat->devname, trunc_name); 142 else 143 memcpy(pts_compat->devname, pts.devname, 144 sizeof(pts_compat->devname)); 145 return (0); 146 } 147 148 int 149 freebsd11_procstat_get_sem_info(struct procstat *procstat, 150 struct filestat *fst, struct freebsd11_semstat *sem_compat, char *errbuf) 151 { 152 struct semstat sem; 153 int r; 154 155 r = procstat_get_sem_info(procstat, fst, &sem, errbuf); 156 if (r != 0) 157 return (r); 158 sem_compat->value = sem.value; 159 sem_compat->mode = sem.mode; 160 return (0); 161 } 162 163 int 164 freebsd11_procstat_get_shm_info(struct procstat *procstat, 165 struct filestat *fst, struct freebsd11_shmstat *shm_compat, char *errbuf) 166 { 167 struct shmstat shm; 168 int r; 169 170 r = procstat_get_shm_info(procstat, fst, &shm, errbuf); 171 if (r != 0) 172 return (r); 173 shm_compat->size = shm.size; 174 shm_compat->mode = shm.mode; 175 return (0); 176 } 177 178 int 179 freebsd11_procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, 180 struct freebsd11_sockstat *sock_compat, char *errbuf) 181 { 182 struct sockstat sock; 183 int r; 184 185 r = procstat_get_socket_info(procstat, fst, &sock, errbuf); 186 if (r != 0) 187 return (r); 188 sock_compat->inp_ppcb = sock.inp_ppcb; 189 sock_compat->so_addr = sock.so_addr; 190 sock_compat->so_pcb = sock.so_pcb; 191 sock_compat->unp_conn = sock.unp_conn; 192 sock_compat->dom_family = sock.dom_family; 193 sock_compat->proto = sock.proto; 194 sock_compat->so_rcv_sb_state = sock.so_rcv_sb_state; 195 sock_compat->so_snd_sb_state = sock.so_snd_sb_state; 196 sock_compat->sa_local = sock.sa_local; 197 sock_compat->sa_peer = sock.sa_peer; 198 sock_compat->type = sock.type; 199 memcpy(sock_compat->dname, sock.dname, sizeof(sock.dname)); 200 return (0); 201 } 202 203 int 204 freebsd11_procstat_get_vnode_info(struct procstat *procstat, 205 struct filestat *fst, struct freebsd11_vnstat *vn_compat, char *errbuf) 206 { 207 struct vnstat vn; 208 int r; 209 210 r = procstat_get_vnode_info(procstat, fst, &vn, errbuf); 211 if (r != 0) 212 return (r); 213 vn_compat->vn_fileid = vn.vn_fileid; 214 vn_compat->vn_size = vn.vn_size; 215 vn_compat->vn_mntdir = vn.vn_mntdir; 216 vn_compat->vn_dev = vn.vn_dev; 217 vn_compat->vn_fsid = vn.vn_fsid; 218 vn_compat->vn_type = vn.vn_type; 219 vn_compat->vn_mode = vn.vn_mode; 220 if (strlen(vn.vn_devname) >= sizeof(vn_compat->vn_devname)) 221 strcpy(vn_compat->vn_devname, trunc_name); 222 else 223 memcpy(vn_compat->vn_devname, vn.vn_devname, 224 sizeof(vn_compat->vn_devname)); 225 return (0); 226 } 227 228 int 229 freebsd12_procstat_get_vnode_info(struct procstat *procstat, 230 struct filestat *fst, struct freebsd12_vnstat *vn_compat, char *errbuf) 231 { 232 struct vnstat vn; 233 int r; 234 235 r = procstat_get_vnode_info(procstat, fst, &vn, errbuf); 236 if (r != 0) 237 return (r); 238 vn_compat->vn_fileid = vn.vn_fileid; 239 vn_compat->vn_size = vn.vn_size; 240 vn_compat->vn_mntdir = vn.vn_mntdir; 241 vn_compat->vn_dev = vn.vn_dev; 242 vn_compat->vn_fsid = vn.vn_fsid; 243 vn_compat->vn_type = vn.vn_type; 244 vn_compat->vn_mode = vn.vn_mode; 245 if (strlen(vn.vn_devname) >= sizeof(vn_compat->vn_devname)) 246 strcpy(vn_compat->vn_devname, trunc_name); 247 else 248 memcpy(vn_compat->vn_devname, vn.vn_devname, 249 sizeof(vn_compat->vn_devname)); 250 return (0); 251 } 252 253 __sym_compat(procstat_get_pts_info, freebsd11_procstat_get_pts_info, FBSD_1.2); 254 __sym_compat(procstat_get_socket_info, freebsd11_procstat_get_socket_info, 255 FBSD_1.2); 256 __sym_compat(procstat_get_vnode_info, freebsd11_procstat_get_vnode_info, 257 FBSD_1.2); 258 __sym_compat(procstat_get_sem_info, freebsd11_procstat_get_sem_info, FBSD_1.3); 259 __sym_compat(procstat_get_shm_info, freebsd11_procstat_get_shm_info, FBSD_1.3); 260 __sym_compat(procstat_get_pts_info, freebsd12_procstat_get_pts_info, FBSD_1.5); 261 __sym_compat(procstat_get_vnode_info, freebsd12_procstat_get_vnode_info, 262 FBSD_1.5); 263