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 #include <sys/param.h> 29 #include <sys/user.h> 30 #include <sys/socket.h> 31 #include <string.h> 32 33 #include "libprocstat.h" 34 35 #define SPECNAMELEN_COMPAT12 63 36 37 struct freebsd11_ptsstat { 38 uint32_t dev; 39 char devname[SPECNAMELEN_COMPAT12 + 1]; 40 }; 41 42 struct freebsd11_vnstat { 43 uint64_t vn_fileid; 44 uint64_t vn_size; 45 char *vn_mntdir; 46 uint32_t vn_dev; 47 uint32_t vn_fsid; 48 int vn_type; 49 uint16_t vn_mode; 50 char vn_devname[SPECNAMELEN_COMPAT12 + 1]; 51 }; 52 struct freebsd11_semstat { 53 uint32_t value; 54 uint16_t mode; 55 }; 56 struct freebsd11_shmstat { 57 uint64_t size; 58 uint16_t mode; 59 }; 60 61 struct freebsd11_sockstat { 62 uint64_t inp_ppcb; 63 uint64_t so_addr; 64 uint64_t so_pcb; 65 uint64_t unp_conn; 66 int dom_family; 67 int proto; 68 int so_rcv_sb_state; 69 int so_snd_sb_state; 70 struct sockaddr_storage sa_local; /* Socket address. */ 71 struct sockaddr_storage sa_peer; /* Peer address. */ 72 int type; 73 char dname[32]; 74 }; 75 76 struct freebsd12_vnstat { 77 uint64_t vn_fileid; 78 uint64_t vn_size; 79 uint64_t vn_dev; 80 uint64_t vn_fsid; 81 char *vn_mntdir; 82 int vn_type; 83 uint16_t vn_mode; 84 char vn_devname[SPECNAMELEN_COMPAT12 + 1]; 85 }; 86 struct freebsd12_ptsstat { 87 uint64_t dev; 88 char devname[SPECNAMELEN_COMPAT12 + 1]; 89 }; 90 91 int freebsd11_procstat_get_pts_info(struct procstat *procstat, 92 struct filestat *fst, struct freebsd11_ptsstat *pts, char *errbuf); 93 int freebsd12_procstat_get_pts_info(struct procstat *procstat, 94 struct filestat *fst, struct freebsd12_ptsstat *pts_compat, char *errbuf); 95 int freebsd11_procstat_get_sem_info(struct procstat *procstat, 96 struct filestat *fst, struct freebsd11_semstat *sem, char *errbuf); 97 int freebsd11_procstat_get_shm_info(struct procstat *procstat, 98 struct filestat *fst, struct freebsd11_shmstat *shm, char *errbuf); 99 int freebsd11_procstat_get_socket_info(struct procstat *procstat, 100 struct filestat *fst, struct freebsd11_sockstat *sock, char *errbuf); 101 int freebsd11_procstat_get_vnode_info(struct procstat *procstat, 102 struct filestat *fst, struct freebsd11_vnstat *vn, char *errbuf); 103 int freebsd12_procstat_get_vnode_info(struct procstat *procstat, 104 struct filestat *fst, struct freebsd12_vnstat *vn_compat, char *errbuf); 105 106 static const char trunc_name[] = "<TRUNCATED>"; 107 108 int 109 freebsd11_procstat_get_pts_info(struct procstat *procstat, 110 struct filestat *fst, struct freebsd11_ptsstat *pts_compat, char *errbuf) 111 { 112 struct ptsstat pts; 113 int r; 114 115 r = procstat_get_pts_info(procstat, fst, &pts, errbuf); 116 if (r != 0) 117 return (r); 118 pts_compat->dev = pts.dev; 119 if (strlen(pts.devname) >= sizeof(pts_compat->devname)) 120 strcpy(pts_compat->devname, trunc_name); 121 else 122 memcpy(pts_compat->devname, pts.devname, 123 sizeof(pts_compat->devname)); 124 return (0); 125 } 126 127 int 128 freebsd12_procstat_get_pts_info(struct procstat *procstat, 129 struct filestat *fst, struct freebsd12_ptsstat *pts_compat, char *errbuf) 130 { 131 struct ptsstat pts; 132 int r; 133 134 r = procstat_get_pts_info(procstat, fst, &pts, errbuf); 135 if (r != 0) 136 return (r); 137 pts_compat->dev = pts.dev; 138 if (strlen(pts.devname) >= sizeof(pts_compat->devname)) 139 strcpy(pts_compat->devname, trunc_name); 140 else 141 memcpy(pts_compat->devname, pts.devname, 142 sizeof(pts_compat->devname)); 143 return (0); 144 } 145 146 int 147 freebsd11_procstat_get_sem_info(struct procstat *procstat, 148 struct filestat *fst, struct freebsd11_semstat *sem_compat, char *errbuf) 149 { 150 struct semstat sem; 151 int r; 152 153 r = procstat_get_sem_info(procstat, fst, &sem, errbuf); 154 if (r != 0) 155 return (r); 156 sem_compat->value = sem.value; 157 sem_compat->mode = sem.mode; 158 return (0); 159 } 160 161 int 162 freebsd11_procstat_get_shm_info(struct procstat *procstat, 163 struct filestat *fst, struct freebsd11_shmstat *shm_compat, char *errbuf) 164 { 165 struct shmstat shm; 166 int r; 167 168 r = procstat_get_shm_info(procstat, fst, &shm, errbuf); 169 if (r != 0) 170 return (r); 171 shm_compat->size = shm.size; 172 shm_compat->mode = shm.mode; 173 return (0); 174 } 175 176 int 177 freebsd11_procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, 178 struct freebsd11_sockstat *sock_compat, char *errbuf) 179 { 180 struct sockstat sock; 181 int r; 182 183 r = procstat_get_socket_info(procstat, fst, &sock, errbuf); 184 if (r != 0) 185 return (r); 186 sock_compat->inp_ppcb = sock.inp_ppcb; 187 sock_compat->so_addr = sock.so_addr; 188 sock_compat->so_pcb = sock.so_pcb; 189 sock_compat->unp_conn = sock.unp_conn; 190 sock_compat->dom_family = sock.dom_family; 191 sock_compat->proto = sock.proto; 192 sock_compat->so_rcv_sb_state = sock.so_rcv_sb_state; 193 sock_compat->so_snd_sb_state = sock.so_snd_sb_state; 194 sock_compat->sa_local = sock.sa_local; 195 sock_compat->sa_peer = sock.sa_peer; 196 sock_compat->type = sock.type; 197 memcpy(sock_compat->dname, sock.dname, sizeof(sock.dname)); 198 return (0); 199 } 200 201 int 202 freebsd11_procstat_get_vnode_info(struct procstat *procstat, 203 struct filestat *fst, struct freebsd11_vnstat *vn_compat, char *errbuf) 204 { 205 struct vnstat vn; 206 int r; 207 208 r = procstat_get_vnode_info(procstat, fst, &vn, errbuf); 209 if (r != 0) 210 return (r); 211 vn_compat->vn_fileid = vn.vn_fileid; 212 vn_compat->vn_size = vn.vn_size; 213 vn_compat->vn_mntdir = vn.vn_mntdir; 214 vn_compat->vn_dev = vn.vn_dev; 215 vn_compat->vn_fsid = vn.vn_fsid; 216 vn_compat->vn_type = vn.vn_type; 217 vn_compat->vn_mode = vn.vn_mode; 218 if (strlen(vn.vn_devname) >= sizeof(vn_compat->vn_devname)) 219 strcpy(vn_compat->vn_devname, trunc_name); 220 else 221 memcpy(vn_compat->vn_devname, vn.vn_devname, 222 sizeof(vn_compat->vn_devname)); 223 return (0); 224 } 225 226 int 227 freebsd12_procstat_get_vnode_info(struct procstat *procstat, 228 struct filestat *fst, struct freebsd12_vnstat *vn_compat, char *errbuf) 229 { 230 struct vnstat vn; 231 int r; 232 233 r = procstat_get_vnode_info(procstat, fst, &vn, errbuf); 234 if (r != 0) 235 return (r); 236 vn_compat->vn_fileid = vn.vn_fileid; 237 vn_compat->vn_size = vn.vn_size; 238 vn_compat->vn_mntdir = vn.vn_mntdir; 239 vn_compat->vn_dev = vn.vn_dev; 240 vn_compat->vn_fsid = vn.vn_fsid; 241 vn_compat->vn_type = vn.vn_type; 242 vn_compat->vn_mode = vn.vn_mode; 243 if (strlen(vn.vn_devname) >= sizeof(vn_compat->vn_devname)) 244 strcpy(vn_compat->vn_devname, trunc_name); 245 else 246 memcpy(vn_compat->vn_devname, vn.vn_devname, 247 sizeof(vn_compat->vn_devname)); 248 return (0); 249 } 250 251 __sym_compat(procstat_get_pts_info, freebsd11_procstat_get_pts_info, FBSD_1.2); 252 __sym_compat(procstat_get_socket_info, freebsd11_procstat_get_socket_info, 253 FBSD_1.2); 254 __sym_compat(procstat_get_vnode_info, freebsd11_procstat_get_vnode_info, 255 FBSD_1.2); 256 __sym_compat(procstat_get_sem_info, freebsd11_procstat_get_sem_info, FBSD_1.3); 257 __sym_compat(procstat_get_shm_info, freebsd11_procstat_get_shm_info, FBSD_1.3); 258 __sym_compat(procstat_get_pts_info, freebsd12_procstat_get_pts_info, FBSD_1.5); 259 __sym_compat(procstat_get_vnode_info, freebsd12_procstat_get_vnode_info, 260 FBSD_1.5); 261