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