1521fa314SDavid van Moolenbroek 2521fa314SDavid van Moolenbroek #include "inc.h" 3521fa314SDavid van Moolenbroek 4521fa314SDavid van Moolenbroek #include <fcntl.h> 5521fa314SDavid van Moolenbroek #include <unistd.h> 6521fa314SDavid van Moolenbroek #include <dirent.h> 7521fa314SDavid van Moolenbroek #include <sys/mount.h> 8521fa314SDavid van Moolenbroek #include <sys/resource.h> 9c38dbb97SDavid van Moolenbroek #include <sys/socket.h> 10c38dbb97SDavid van Moolenbroek #include <sys/un.h> 11c38dbb97SDavid van Moolenbroek #include <netinet/in.h> 12c38dbb97SDavid van Moolenbroek #if 0 /* not yet, header is missing */ 13c38dbb97SDavid van Moolenbroek #include <netbt/bluetooth.h> 14c38dbb97SDavid van Moolenbroek #endif 15c38dbb97SDavid van Moolenbroek #include <arpa/inet.h> 16521fa314SDavid van Moolenbroek 17521fa314SDavid van Moolenbroek /* 18521fa314SDavid van Moolenbroek * This function should always be used when printing a file descriptor. It 19521fa314SDavid van Moolenbroek * currently offers no benefit, but will in the future allow for features such 20521fa314SDavid van Moolenbroek * as color highlighting and tracking of specific open files (TODO). 21521fa314SDavid van Moolenbroek */ 22521fa314SDavid van Moolenbroek void 23521fa314SDavid van Moolenbroek put_fd(struct trace_proc * proc, const char * name, int fd) 24521fa314SDavid van Moolenbroek { 25521fa314SDavid van Moolenbroek 26521fa314SDavid van Moolenbroek put_value(proc, name, "%d", fd); 27521fa314SDavid van Moolenbroek } 28521fa314SDavid van Moolenbroek 29521fa314SDavid van Moolenbroek static int 30521fa314SDavid van Moolenbroek vfs_read_out(struct trace_proc * proc, const message * m_out) 31521fa314SDavid van Moolenbroek { 32521fa314SDavid van Moolenbroek 33521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_readwrite.fd); 34521fa314SDavid van Moolenbroek 35521fa314SDavid van Moolenbroek return CT_NOTDONE; 36521fa314SDavid van Moolenbroek } 37521fa314SDavid van Moolenbroek 38521fa314SDavid van Moolenbroek static void 39521fa314SDavid van Moolenbroek vfs_read_in(struct trace_proc * proc, const message * m_out, 40521fa314SDavid van Moolenbroek const message * m_in, int failed) 41521fa314SDavid van Moolenbroek { 42521fa314SDavid van Moolenbroek 43521fa314SDavid van Moolenbroek put_buf(proc, "buf", failed, m_out->m_lc_vfs_readwrite.buf, 44521fa314SDavid van Moolenbroek m_in->m_type); 45521fa314SDavid van Moolenbroek put_value(proc, "len", "%zu", m_out->m_lc_vfs_readwrite.len); 46521fa314SDavid van Moolenbroek put_equals(proc); 47521fa314SDavid van Moolenbroek put_result(proc); 48521fa314SDavid van Moolenbroek } 49521fa314SDavid van Moolenbroek 50521fa314SDavid van Moolenbroek static int 51521fa314SDavid van Moolenbroek vfs_write_out(struct trace_proc * proc, const message * m_out) 52521fa314SDavid van Moolenbroek { 53521fa314SDavid van Moolenbroek 54521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_readwrite.fd); 55521fa314SDavid van Moolenbroek put_buf(proc, "buf", 0, m_out->m_lc_vfs_readwrite.buf, 56521fa314SDavid van Moolenbroek m_out->m_lc_vfs_readwrite.len); 57521fa314SDavid van Moolenbroek put_value(proc, "len", "%zu", m_out->m_lc_vfs_readwrite.len); 58521fa314SDavid van Moolenbroek 59521fa314SDavid van Moolenbroek return CT_DONE; 60521fa314SDavid van Moolenbroek } 61521fa314SDavid van Moolenbroek 62521fa314SDavid van Moolenbroek static void 63521fa314SDavid van Moolenbroek put_lseek_whence(struct trace_proc * proc, const char * name, int whence) 64521fa314SDavid van Moolenbroek { 65521fa314SDavid van Moolenbroek const char *text = NULL; 66521fa314SDavid van Moolenbroek 67521fa314SDavid van Moolenbroek if (!valuesonly) { 68521fa314SDavid van Moolenbroek switch (whence) { 69521fa314SDavid van Moolenbroek TEXT(SEEK_SET); 70521fa314SDavid van Moolenbroek TEXT(SEEK_CUR); 71521fa314SDavid van Moolenbroek TEXT(SEEK_END); 72521fa314SDavid van Moolenbroek } 73521fa314SDavid van Moolenbroek } 74521fa314SDavid van Moolenbroek 75521fa314SDavid van Moolenbroek if (text != NULL) 76521fa314SDavid van Moolenbroek put_field(proc, name, text); 77521fa314SDavid van Moolenbroek else 78521fa314SDavid van Moolenbroek put_value(proc, name, "%d", whence); 79521fa314SDavid van Moolenbroek } 80521fa314SDavid van Moolenbroek 81521fa314SDavid van Moolenbroek static int 82521fa314SDavid van Moolenbroek vfs_lseek_out(struct trace_proc * proc, const message * m_out) 83521fa314SDavid van Moolenbroek { 84521fa314SDavid van Moolenbroek 85521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_lseek.fd); 86521fa314SDavid van Moolenbroek put_value(proc, "offset", "%"PRId64, m_out->m_lc_vfs_lseek.offset); 87521fa314SDavid van Moolenbroek put_lseek_whence(proc, "whence", m_out->m_lc_vfs_lseek.whence); 88521fa314SDavid van Moolenbroek 89521fa314SDavid van Moolenbroek return CT_DONE; 90521fa314SDavid van Moolenbroek } 91521fa314SDavid van Moolenbroek 92521fa314SDavid van Moolenbroek static void 93521fa314SDavid van Moolenbroek vfs_lseek_in(struct trace_proc * proc, const message * __unused m_out, 94521fa314SDavid van Moolenbroek const message * m_in, int failed) 95521fa314SDavid van Moolenbroek { 96521fa314SDavid van Moolenbroek 97521fa314SDavid van Moolenbroek if (!failed) 98521fa314SDavid van Moolenbroek put_value(proc, NULL, "%"PRId64, m_in->m_vfs_lc_lseek.offset); 99521fa314SDavid van Moolenbroek else 100521fa314SDavid van Moolenbroek put_result(proc); 101521fa314SDavid van Moolenbroek } 102521fa314SDavid van Moolenbroek 103521fa314SDavid van Moolenbroek static const struct flags open_flags[] = { 104521fa314SDavid van Moolenbroek FLAG_MASK(O_ACCMODE, O_RDONLY), 105521fa314SDavid van Moolenbroek FLAG_MASK(O_ACCMODE, O_WRONLY), 106521fa314SDavid van Moolenbroek FLAG_MASK(O_ACCMODE, O_RDWR), 107521fa314SDavid van Moolenbroek #define ACCMODE_ENTRIES 3 /* the first N entries are for O_ACCMODE */ 108521fa314SDavid van Moolenbroek FLAG(O_NONBLOCK), 109521fa314SDavid van Moolenbroek FLAG(O_APPEND), 110521fa314SDavid van Moolenbroek FLAG(O_SHLOCK), 111521fa314SDavid van Moolenbroek FLAG(O_EXLOCK), 112521fa314SDavid van Moolenbroek FLAG(O_ASYNC), 113521fa314SDavid van Moolenbroek FLAG(O_SYNC), 114521fa314SDavid van Moolenbroek FLAG(O_NOFOLLOW), 115521fa314SDavid van Moolenbroek FLAG(O_CREAT), 116521fa314SDavid van Moolenbroek FLAG(O_TRUNC), 117521fa314SDavid van Moolenbroek FLAG(O_EXCL), 118521fa314SDavid van Moolenbroek FLAG(O_NOCTTY), 119521fa314SDavid van Moolenbroek FLAG(O_DSYNC), 120521fa314SDavid van Moolenbroek FLAG(O_RSYNC), 121521fa314SDavid van Moolenbroek FLAG(O_ALT_IO), 122521fa314SDavid van Moolenbroek FLAG(O_DIRECT), 123521fa314SDavid van Moolenbroek FLAG(O_DIRECTORY), 124521fa314SDavid van Moolenbroek FLAG(O_CLOEXEC), 125521fa314SDavid van Moolenbroek FLAG(O_SEARCH), 126521fa314SDavid van Moolenbroek FLAG(O_NOSIGPIPE), 127521fa314SDavid van Moolenbroek }; 128521fa314SDavid van Moolenbroek 129521fa314SDavid van Moolenbroek static void 130521fa314SDavid van Moolenbroek put_open_flags(struct trace_proc * proc, const char * name, int value, 131521fa314SDavid van Moolenbroek int full) 132521fa314SDavid van Moolenbroek { 133521fa314SDavid van Moolenbroek const struct flags *fp; 134521fa314SDavid van Moolenbroek unsigned int num; 135521fa314SDavid van Moolenbroek 136521fa314SDavid van Moolenbroek fp = open_flags; 137521fa314SDavid van Moolenbroek num = COUNT(open_flags); 138521fa314SDavid van Moolenbroek 139521fa314SDavid van Moolenbroek /* 140521fa314SDavid van Moolenbroek * If we're not printing a full open()-style set of flags, but instead 141521fa314SDavid van Moolenbroek * just a loose set of flags, then skip the access mode altogether, 142521fa314SDavid van Moolenbroek * otherwise we'd be printing O_RDONLY when no access mode is given. 143521fa314SDavid van Moolenbroek */ 144521fa314SDavid van Moolenbroek if (!full) { 145521fa314SDavid van Moolenbroek fp += ACCMODE_ENTRIES; 146521fa314SDavid van Moolenbroek num -= ACCMODE_ENTRIES; 147521fa314SDavid van Moolenbroek } 148521fa314SDavid van Moolenbroek 149521fa314SDavid van Moolenbroek put_flags(proc, name, fp, num, "0x%x", value); 150521fa314SDavid van Moolenbroek } 151521fa314SDavid van Moolenbroek 152521fa314SDavid van Moolenbroek static const struct flags mode_flags[] = { 153521fa314SDavid van Moolenbroek FLAG_MASK(S_IFMT, S_IFIFO), 154521fa314SDavid van Moolenbroek FLAG_MASK(S_IFMT, S_IFCHR), 155521fa314SDavid van Moolenbroek FLAG_MASK(S_IFMT, S_IFDIR), 156521fa314SDavid van Moolenbroek FLAG_MASK(S_IFMT, S_IFBLK), 157521fa314SDavid van Moolenbroek FLAG_MASK(S_IFMT, S_IFREG), 158521fa314SDavid van Moolenbroek FLAG_MASK(S_IFMT, S_IFLNK), 159521fa314SDavid van Moolenbroek FLAG_MASK(S_IFMT, S_IFSOCK), 160521fa314SDavid van Moolenbroek FLAG_MASK(S_IFMT, S_IFWHT), 161521fa314SDavid van Moolenbroek FLAG(S_ARCH1), 162521fa314SDavid van Moolenbroek FLAG(S_ARCH2), 163521fa314SDavid van Moolenbroek FLAG(S_ISUID), 164521fa314SDavid van Moolenbroek FLAG(S_ISGID), 165521fa314SDavid van Moolenbroek FLAG(S_ISTXT), 166521fa314SDavid van Moolenbroek }; 167521fa314SDavid van Moolenbroek 168521fa314SDavid van Moolenbroek /* Do not use %04o instead of 0%03o; it is octal even if greater than 0777. */ 169521fa314SDavid van Moolenbroek #define put_mode(p, n, v) \ 170521fa314SDavid van Moolenbroek put_flags(p, n, mode_flags, COUNT(mode_flags), "0%03o", v) 171521fa314SDavid van Moolenbroek 172521fa314SDavid van Moolenbroek static void 173521fa314SDavid van Moolenbroek put_path(struct trace_proc * proc, const message * m_out) 174521fa314SDavid van Moolenbroek { 175521fa314SDavid van Moolenbroek size_t len; 176521fa314SDavid van Moolenbroek 177521fa314SDavid van Moolenbroek if ((len = m_out->m_lc_vfs_path.len) <= M_PATH_STRING_MAX) 178521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_LOCADDR | PF_PATH, 179521fa314SDavid van Moolenbroek (vir_bytes)m_out->m_lc_vfs_path.buf, len); 180521fa314SDavid van Moolenbroek else 181521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_path.name, len); 182521fa314SDavid van Moolenbroek } 183521fa314SDavid van Moolenbroek 184521fa314SDavid van Moolenbroek static int 185521fa314SDavid van Moolenbroek vfs_open_out(struct trace_proc * proc, const message * m_out) 186521fa314SDavid van Moolenbroek { 187521fa314SDavid van Moolenbroek 188521fa314SDavid van Moolenbroek put_path(proc, m_out); 189521fa314SDavid van Moolenbroek put_open_flags(proc, "flags", m_out->m_lc_vfs_path.flags, 190521fa314SDavid van Moolenbroek TRUE /*full*/); 191521fa314SDavid van Moolenbroek 192521fa314SDavid van Moolenbroek return CT_DONE; 193521fa314SDavid van Moolenbroek } 194521fa314SDavid van Moolenbroek 195521fa314SDavid van Moolenbroek /* This function is shared between creat and open. */ 196521fa314SDavid van Moolenbroek static void 197521fa314SDavid van Moolenbroek vfs_open_in(struct trace_proc * proc, const message * __unused m_out, 198521fa314SDavid van Moolenbroek const message * m_in, int failed) 199521fa314SDavid van Moolenbroek { 200521fa314SDavid van Moolenbroek 201521fa314SDavid van Moolenbroek if (!failed) 202521fa314SDavid van Moolenbroek put_fd(proc, NULL, m_in->m_type); 203521fa314SDavid van Moolenbroek else 204521fa314SDavid van Moolenbroek put_result(proc); 205521fa314SDavid van Moolenbroek } 206521fa314SDavid van Moolenbroek 207521fa314SDavid van Moolenbroek static int 208521fa314SDavid van Moolenbroek vfs_creat_out(struct trace_proc * proc, const message * m_out) 209521fa314SDavid van Moolenbroek { 210521fa314SDavid van Moolenbroek 211521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_creat.name, 212521fa314SDavid van Moolenbroek m_out->m_lc_vfs_creat.len); 213521fa314SDavid van Moolenbroek put_open_flags(proc, "flags", m_out->m_lc_vfs_creat.flags, 214521fa314SDavid van Moolenbroek TRUE /*full*/); 215521fa314SDavid van Moolenbroek put_mode(proc, "mode", m_out->m_lc_vfs_creat.mode); 216521fa314SDavid van Moolenbroek 217521fa314SDavid van Moolenbroek return CT_DONE; 218521fa314SDavid van Moolenbroek } 219521fa314SDavid van Moolenbroek 220521fa314SDavid van Moolenbroek static int 221521fa314SDavid van Moolenbroek vfs_close_out(struct trace_proc * proc, const message * m_out) 222521fa314SDavid van Moolenbroek { 223521fa314SDavid van Moolenbroek 224521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_close.fd); 225521fa314SDavid van Moolenbroek 226521fa314SDavid van Moolenbroek return CT_DONE; 227521fa314SDavid van Moolenbroek } 228521fa314SDavid van Moolenbroek 229521fa314SDavid van Moolenbroek /* This function is used for link, rename, and symlink. */ 230521fa314SDavid van Moolenbroek static int 231521fa314SDavid van Moolenbroek vfs_link_out(struct trace_proc * proc, const message * m_out) 232521fa314SDavid van Moolenbroek { 233521fa314SDavid van Moolenbroek 234521fa314SDavid van Moolenbroek put_buf(proc, "path1", PF_PATH, m_out->m_lc_vfs_link.name1, 235521fa314SDavid van Moolenbroek m_out->m_lc_vfs_link.len1); 236521fa314SDavid van Moolenbroek put_buf(proc, "path2", PF_PATH, m_out->m_lc_vfs_link.name2, 237521fa314SDavid van Moolenbroek m_out->m_lc_vfs_link.len2); 238521fa314SDavid van Moolenbroek 239521fa314SDavid van Moolenbroek return CT_DONE; 240521fa314SDavid van Moolenbroek } 241521fa314SDavid van Moolenbroek 242521fa314SDavid van Moolenbroek static int 243521fa314SDavid van Moolenbroek vfs_path_out(struct trace_proc * proc, const message * m_out) 244521fa314SDavid van Moolenbroek { 245521fa314SDavid van Moolenbroek 246521fa314SDavid van Moolenbroek put_path(proc, m_out); 247521fa314SDavid van Moolenbroek 248521fa314SDavid van Moolenbroek return CT_DONE; 249521fa314SDavid van Moolenbroek } 250521fa314SDavid van Moolenbroek 251521fa314SDavid van Moolenbroek static int 252521fa314SDavid van Moolenbroek vfs_path_mode_out(struct trace_proc * proc, const message * m_out) 253521fa314SDavid van Moolenbroek { 254521fa314SDavid van Moolenbroek 255521fa314SDavid van Moolenbroek put_path(proc, m_out); 256521fa314SDavid van Moolenbroek put_mode(proc, "mode", m_out->m_lc_vfs_path.mode); 257521fa314SDavid van Moolenbroek 258521fa314SDavid van Moolenbroek return CT_DONE; 259521fa314SDavid van Moolenbroek } 260521fa314SDavid van Moolenbroek 261521fa314SDavid van Moolenbroek void 262521fa314SDavid van Moolenbroek put_dev(struct trace_proc * proc, const char * name, dev_t dev) 263521fa314SDavid van Moolenbroek { 264521fa314SDavid van Moolenbroek devmajor_t major; 265521fa314SDavid van Moolenbroek devminor_t minor; 266521fa314SDavid van Moolenbroek 267521fa314SDavid van Moolenbroek major = major(dev); 268521fa314SDavid van Moolenbroek minor = minor(dev); 269521fa314SDavid van Moolenbroek 270521fa314SDavid van Moolenbroek /* The value 0 ("no device") should print as "0". */ 271521fa314SDavid van Moolenbroek if (dev != 0 && makedev(major, minor) == dev && !valuesonly) 272521fa314SDavid van Moolenbroek put_value(proc, name, "<%d,%d>", major, minor); 273521fa314SDavid van Moolenbroek else 274521fa314SDavid van Moolenbroek put_value(proc, name, "%"PRIu64, dev); 275521fa314SDavid van Moolenbroek } 276521fa314SDavid van Moolenbroek 277521fa314SDavid van Moolenbroek static int 278521fa314SDavid van Moolenbroek vfs_mknod_out(struct trace_proc * proc, const message * m_out) 279521fa314SDavid van Moolenbroek { 280521fa314SDavid van Moolenbroek 281521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_mknod.name, 282521fa314SDavid van Moolenbroek m_out->m_lc_vfs_mknod.len); 283521fa314SDavid van Moolenbroek put_mode(proc, "mode", m_out->m_lc_vfs_mknod.mode); 284521fa314SDavid van Moolenbroek put_dev(proc, "dev", m_out->m_lc_vfs_mknod.device); 285521fa314SDavid van Moolenbroek 286521fa314SDavid van Moolenbroek return CT_DONE; 287521fa314SDavid van Moolenbroek } 288521fa314SDavid van Moolenbroek 289521fa314SDavid van Moolenbroek static int 290521fa314SDavid van Moolenbroek vfs_chown_out(struct trace_proc * proc, const message * m_out) 291521fa314SDavid van Moolenbroek { 292521fa314SDavid van Moolenbroek 293521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_chown.name, 294521fa314SDavid van Moolenbroek m_out->m_lc_vfs_chown.len); 295521fa314SDavid van Moolenbroek /* -1 means "keep the current value" so print as signed */ 296521fa314SDavid van Moolenbroek put_value(proc, "owner", "%d", m_out->m_lc_vfs_chown.owner); 297521fa314SDavid van Moolenbroek put_value(proc, "group", "%d", m_out->m_lc_vfs_chown.group); 298521fa314SDavid van Moolenbroek 299521fa314SDavid van Moolenbroek return CT_DONE; 300521fa314SDavid van Moolenbroek } 301521fa314SDavid van Moolenbroek 302521fa314SDavid van Moolenbroek /* TODO: expand this to the full ST_ set. */ 303521fa314SDavid van Moolenbroek static const struct flags mount_flags[] = { 304521fa314SDavid van Moolenbroek FLAG(MNT_RDONLY), 305521fa314SDavid van Moolenbroek }; 306521fa314SDavid van Moolenbroek 307521fa314SDavid van Moolenbroek static int 308521fa314SDavid van Moolenbroek vfs_mount_out(struct trace_proc * proc, const message * m_out) 309521fa314SDavid van Moolenbroek { 310521fa314SDavid van Moolenbroek 311521fa314SDavid van Moolenbroek put_buf(proc, "special", PF_PATH, m_out->m_lc_vfs_mount.dev, 312521fa314SDavid van Moolenbroek m_out->m_lc_vfs_mount.devlen); 313521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_mount.path, 314521fa314SDavid van Moolenbroek m_out->m_lc_vfs_mount.pathlen); 315521fa314SDavid van Moolenbroek put_flags(proc, "flags", mount_flags, COUNT(mount_flags), "0x%x", 316521fa314SDavid van Moolenbroek m_out->m_lc_vfs_mount.flags); 317521fa314SDavid van Moolenbroek put_buf(proc, "type", PF_STRING, m_out->m_lc_vfs_mount.type, 318521fa314SDavid van Moolenbroek m_out->m_lc_vfs_mount.typelen); 319521fa314SDavid van Moolenbroek put_buf(proc, "label", PF_STRING, m_out->m_lc_vfs_mount.label, 320521fa314SDavid van Moolenbroek m_out->m_lc_vfs_mount.labellen); 321521fa314SDavid van Moolenbroek 322521fa314SDavid van Moolenbroek return CT_DONE; 323521fa314SDavid van Moolenbroek } 324521fa314SDavid van Moolenbroek 325521fa314SDavid van Moolenbroek static int 326521fa314SDavid van Moolenbroek vfs_umount_out(struct trace_proc * proc, const message * m_out) 327521fa314SDavid van Moolenbroek { 328521fa314SDavid van Moolenbroek 329521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_umount.name, 330521fa314SDavid van Moolenbroek m_out->m_lc_vfs_umount.namelen); 331521fa314SDavid van Moolenbroek 332521fa314SDavid van Moolenbroek return CT_DONE; 333521fa314SDavid van Moolenbroek } 334521fa314SDavid van Moolenbroek 335521fa314SDavid van Moolenbroek static void 336521fa314SDavid van Moolenbroek vfs_umount_in(struct trace_proc * proc, const message * m_out, 337521fa314SDavid van Moolenbroek const message * __unused m_in, int failed) 338521fa314SDavid van Moolenbroek { 339521fa314SDavid van Moolenbroek 340521fa314SDavid van Moolenbroek put_result(proc); 341521fa314SDavid van Moolenbroek 342521fa314SDavid van Moolenbroek if (!failed) { 343521fa314SDavid van Moolenbroek put_open(proc, NULL, 0, "(", ", "); 344521fa314SDavid van Moolenbroek put_buf(proc, "label", PF_STRING, m_out->m_lc_vfs_umount.label, 345521fa314SDavid van Moolenbroek m_out->m_lc_vfs_umount.labellen); 346521fa314SDavid van Moolenbroek 347521fa314SDavid van Moolenbroek put_close(proc, ")"); 348521fa314SDavid van Moolenbroek } 349521fa314SDavid van Moolenbroek } 350521fa314SDavid van Moolenbroek 351521fa314SDavid van Moolenbroek 352521fa314SDavid van Moolenbroek static const struct flags access_flags[] = { 353521fa314SDavid van Moolenbroek FLAG_ZERO(F_OK), 354521fa314SDavid van Moolenbroek FLAG(R_OK), 355521fa314SDavid van Moolenbroek FLAG(W_OK), 356521fa314SDavid van Moolenbroek FLAG(X_OK), 357521fa314SDavid van Moolenbroek }; 358521fa314SDavid van Moolenbroek 359521fa314SDavid van Moolenbroek static int 360521fa314SDavid van Moolenbroek vfs_access_out(struct trace_proc * proc, const message * m_out) 361521fa314SDavid van Moolenbroek { 362521fa314SDavid van Moolenbroek 363521fa314SDavid van Moolenbroek put_path(proc, m_out); 364521fa314SDavid van Moolenbroek put_flags(proc, "mode", access_flags, COUNT(access_flags), "0x%x", 365521fa314SDavid van Moolenbroek m_out->m_lc_vfs_path.mode); 366521fa314SDavid van Moolenbroek 367521fa314SDavid van Moolenbroek return CT_DONE; 368521fa314SDavid van Moolenbroek } 369521fa314SDavid van Moolenbroek 370521fa314SDavid van Moolenbroek static int 371521fa314SDavid van Moolenbroek vfs_readlink_out(struct trace_proc * proc, const message * m_out) 372521fa314SDavid van Moolenbroek { 373521fa314SDavid van Moolenbroek 374521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_readlink.name, 375521fa314SDavid van Moolenbroek m_out->m_lc_vfs_readlink.namelen); 376521fa314SDavid van Moolenbroek 377521fa314SDavid van Moolenbroek return CT_NOTDONE; 378521fa314SDavid van Moolenbroek } 379521fa314SDavid van Moolenbroek 380521fa314SDavid van Moolenbroek static void 381521fa314SDavid van Moolenbroek vfs_readlink_in(struct trace_proc * proc, const message * m_out, 382521fa314SDavid van Moolenbroek const message * m_in, int failed) 383521fa314SDavid van Moolenbroek { 384521fa314SDavid van Moolenbroek 385521fa314SDavid van Moolenbroek /* The call does not return a string, so do not use PF_STRING here. */ 386521fa314SDavid van Moolenbroek put_buf(proc, "buf", failed, m_out->m_lc_vfs_readlink.buf, 387521fa314SDavid van Moolenbroek m_in->m_type); 388521fa314SDavid van Moolenbroek put_value(proc, "bufsize", "%zd", m_out->m_lc_vfs_readlink.bufsize); 389521fa314SDavid van Moolenbroek put_equals(proc); 390521fa314SDavid van Moolenbroek put_result(proc); 391521fa314SDavid van Moolenbroek } 392521fa314SDavid van Moolenbroek 393521fa314SDavid van Moolenbroek static void 394521fa314SDavid van Moolenbroek put_struct_stat(struct trace_proc * proc, const char * name, int flags, 395521fa314SDavid van Moolenbroek vir_bytes addr) 396521fa314SDavid van Moolenbroek { 397521fa314SDavid van Moolenbroek struct stat buf; 398521fa314SDavid van Moolenbroek int is_special; 399521fa314SDavid van Moolenbroek 400521fa314SDavid van Moolenbroek if (!put_open_struct(proc, name, flags, addr, &buf, sizeof(buf))) 401521fa314SDavid van Moolenbroek return; 402521fa314SDavid van Moolenbroek 403521fa314SDavid van Moolenbroek /* 404521fa314SDavid van Moolenbroek * The combination of struct stat's frequent usage and large number of 405521fa314SDavid van Moolenbroek * fields makes this structure a pain to print. For now, the idea is 406521fa314SDavid van Moolenbroek * that for verbosity level 0, we print the mode, and the target device 407521fa314SDavid van Moolenbroek * for block/char special files or the file size for all other files. 408521fa314SDavid van Moolenbroek * For higher verbosity levels, largely maintain the structure's own 409521fa314SDavid van Moolenbroek * order of fields. Violate this general structure printing rule for 410521fa314SDavid van Moolenbroek * some fields though, because the actual field order in struct stat is 411521fa314SDavid van Moolenbroek * downright ridiculous. Like elsewhere, for verbosity level 1 print 412521fa314SDavid van Moolenbroek * all fields with meaningful values, and for verbosity level 2 just 413521fa314SDavid van Moolenbroek * print everything, including fields that are known to be not yet 414521fa314SDavid van Moolenbroek * supported and fields that contain known values. 415521fa314SDavid van Moolenbroek */ 416521fa314SDavid van Moolenbroek is_special = (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode)); 417521fa314SDavid van Moolenbroek 418521fa314SDavid van Moolenbroek if (verbose > 0) { 419521fa314SDavid van Moolenbroek put_dev(proc, "st_dev", buf.st_dev); 420521fa314SDavid van Moolenbroek put_value(proc, "st_ino", "%"PRId64, buf.st_ino); 421521fa314SDavid van Moolenbroek } 422521fa314SDavid van Moolenbroek put_mode(proc, "st_mode", buf.st_mode); 423521fa314SDavid van Moolenbroek if (verbose > 0) { 424521fa314SDavid van Moolenbroek put_value(proc, "st_nlink", "%u", buf.st_nlink); 425521fa314SDavid van Moolenbroek put_value(proc, "st_uid", "%u", buf.st_uid); 426521fa314SDavid van Moolenbroek put_value(proc, "st_gid", "%u", buf.st_gid); 427521fa314SDavid van Moolenbroek } 428521fa314SDavid van Moolenbroek if (is_special || verbose > 1) 429521fa314SDavid van Moolenbroek put_dev(proc, "st_rdev", buf.st_rdev); 430521fa314SDavid van Moolenbroek if (verbose > 0) { 431521fa314SDavid van Moolenbroek /* 432521fa314SDavid van Moolenbroek * TODO: print the nanosecond part, but possibly only if we are 433521fa314SDavid van Moolenbroek * not actually interpreting the time as a date (another TODO), 434521fa314SDavid van Moolenbroek * and/or possibly only with verbose > 1 (largely unsupported). 435521fa314SDavid van Moolenbroek */ 436521fa314SDavid van Moolenbroek put_time(proc, "st_atime", buf.st_atime); 437521fa314SDavid van Moolenbroek put_time(proc, "st_mtime", buf.st_mtime); 438521fa314SDavid van Moolenbroek put_time(proc, "st_ctime", buf.st_ctime); 439521fa314SDavid van Moolenbroek } 440521fa314SDavid van Moolenbroek if (verbose > 1) /* not yet supported on MINIX3 */ 441521fa314SDavid van Moolenbroek put_time(proc, "st_birthtime", buf.st_birthtime); 442521fa314SDavid van Moolenbroek if (!is_special || verbose > 1) 443521fa314SDavid van Moolenbroek put_value(proc, "st_size", "%"PRId64, buf.st_size); 444521fa314SDavid van Moolenbroek if (verbose > 0) { 445521fa314SDavid van Moolenbroek put_value(proc, "st_blocks", "%"PRId64, buf.st_blocks); 446521fa314SDavid van Moolenbroek put_value(proc, "st_blksize", "%"PRId32, buf.st_blksize); 447521fa314SDavid van Moolenbroek } 448521fa314SDavid van Moolenbroek if (verbose > 1) { 449521fa314SDavid van Moolenbroek put_value(proc, "st_flags", "%"PRIu32, buf.st_flags); 450521fa314SDavid van Moolenbroek put_value(proc, "st_gen", "%"PRIu32, buf.st_gen); 451521fa314SDavid van Moolenbroek } 452521fa314SDavid van Moolenbroek 453521fa314SDavid van Moolenbroek put_close_struct(proc, verbose > 1); 454521fa314SDavid van Moolenbroek } 455521fa314SDavid van Moolenbroek 456521fa314SDavid van Moolenbroek static int 457521fa314SDavid van Moolenbroek vfs_stat_out(struct trace_proc * proc, const message * m_out) 458521fa314SDavid van Moolenbroek { 459521fa314SDavid van Moolenbroek 460521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_stat.name, 461521fa314SDavid van Moolenbroek m_out->m_lc_vfs_stat.len); 462521fa314SDavid van Moolenbroek 463521fa314SDavid van Moolenbroek return CT_NOTDONE; 464521fa314SDavid van Moolenbroek } 465521fa314SDavid van Moolenbroek 466521fa314SDavid van Moolenbroek static void 467521fa314SDavid van Moolenbroek vfs_stat_in(struct trace_proc * proc, const message * m_out, 468521fa314SDavid van Moolenbroek const message * __unused m_in, int failed) 469521fa314SDavid van Moolenbroek { 470521fa314SDavid van Moolenbroek 471521fa314SDavid van Moolenbroek put_struct_stat(proc, "buf", failed, m_out->m_lc_vfs_stat.buf); 472521fa314SDavid van Moolenbroek put_equals(proc); 473521fa314SDavid van Moolenbroek put_result(proc); 474521fa314SDavid van Moolenbroek } 475521fa314SDavid van Moolenbroek 476521fa314SDavid van Moolenbroek static int 477521fa314SDavid van Moolenbroek vfs_fstat_out(struct trace_proc * proc, const message * m_out) 478521fa314SDavid van Moolenbroek { 479521fa314SDavid van Moolenbroek 480521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_fstat.fd); 481521fa314SDavid van Moolenbroek 482521fa314SDavid van Moolenbroek return CT_NOTDONE; 483521fa314SDavid van Moolenbroek } 484521fa314SDavid van Moolenbroek 485521fa314SDavid van Moolenbroek static void 486521fa314SDavid van Moolenbroek vfs_fstat_in(struct trace_proc * proc, const message * m_out, 487521fa314SDavid van Moolenbroek const message * __unused m_in, int failed) 488521fa314SDavid van Moolenbroek { 489521fa314SDavid van Moolenbroek 490521fa314SDavid van Moolenbroek put_struct_stat(proc, "buf", failed, m_out->m_lc_vfs_fstat.buf); 491521fa314SDavid van Moolenbroek put_equals(proc); 492521fa314SDavid van Moolenbroek put_result(proc); 493521fa314SDavid van Moolenbroek } 494521fa314SDavid van Moolenbroek 495521fa314SDavid van Moolenbroek static int 496521fa314SDavid van Moolenbroek vfs_ioctl_out(struct trace_proc * proc, const message * m_out) 497521fa314SDavid van Moolenbroek { 498521fa314SDavid van Moolenbroek 499521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_ioctl.fd); 500521fa314SDavid van Moolenbroek put_ioctl_req(proc, "req", m_out->m_lc_vfs_ioctl.req, 501521fa314SDavid van Moolenbroek FALSE /*is_svrctl*/); 502521fa314SDavid van Moolenbroek return put_ioctl_arg_out(proc, "arg", m_out->m_lc_vfs_ioctl.req, 503521fa314SDavid van Moolenbroek (vir_bytes)m_out->m_lc_vfs_ioctl.arg, FALSE /*is_svrctl*/); 504521fa314SDavid van Moolenbroek } 505521fa314SDavid van Moolenbroek 506521fa314SDavid van Moolenbroek static void 507521fa314SDavid van Moolenbroek vfs_ioctl_in(struct trace_proc * proc, const message * m_out, 508521fa314SDavid van Moolenbroek const message * __unused m_in, int failed) 509521fa314SDavid van Moolenbroek { 510521fa314SDavid van Moolenbroek 511521fa314SDavid van Moolenbroek put_ioctl_arg_in(proc, "arg", failed, m_out->m_lc_vfs_ioctl.req, 512521fa314SDavid van Moolenbroek (vir_bytes)m_out->m_lc_vfs_ioctl.arg, FALSE /*is_svrctl*/); 513521fa314SDavid van Moolenbroek } 514521fa314SDavid van Moolenbroek 515521fa314SDavid van Moolenbroek static void 516521fa314SDavid van Moolenbroek put_fcntl_cmd(struct trace_proc * proc, const char * name, int cmd) 517521fa314SDavid van Moolenbroek { 518521fa314SDavid van Moolenbroek const char *text = NULL; 519521fa314SDavid van Moolenbroek 520521fa314SDavid van Moolenbroek if (!valuesonly) { 521521fa314SDavid van Moolenbroek switch (cmd) { 522521fa314SDavid van Moolenbroek TEXT(F_DUPFD); 523521fa314SDavid van Moolenbroek TEXT(F_GETFD); 524521fa314SDavid van Moolenbroek TEXT(F_SETFD); 525521fa314SDavid van Moolenbroek TEXT(F_GETFL); 526521fa314SDavid van Moolenbroek TEXT(F_SETFL); 527521fa314SDavid van Moolenbroek TEXT(F_GETOWN); 528521fa314SDavid van Moolenbroek TEXT(F_SETOWN); 529521fa314SDavid van Moolenbroek TEXT(F_GETLK); 530521fa314SDavid van Moolenbroek TEXT(F_SETLK); 531521fa314SDavid van Moolenbroek TEXT(F_SETLKW); 532521fa314SDavid van Moolenbroek TEXT(F_CLOSEM); 533521fa314SDavid van Moolenbroek TEXT(F_MAXFD); 534521fa314SDavid van Moolenbroek TEXT(F_DUPFD_CLOEXEC); 535521fa314SDavid van Moolenbroek TEXT(F_GETNOSIGPIPE); 536521fa314SDavid van Moolenbroek TEXT(F_SETNOSIGPIPE); 537521fa314SDavid van Moolenbroek TEXT(F_FREESP); 538521fa314SDavid van Moolenbroek TEXT(F_FLUSH_FS_CACHE); 539521fa314SDavid van Moolenbroek } 540521fa314SDavid van Moolenbroek } 541521fa314SDavid van Moolenbroek 542521fa314SDavid van Moolenbroek if (text != NULL) 543521fa314SDavid van Moolenbroek put_field(proc, name, text); 544521fa314SDavid van Moolenbroek else 545521fa314SDavid van Moolenbroek put_value(proc, name, "%d", cmd); 546521fa314SDavid van Moolenbroek } 547521fa314SDavid van Moolenbroek 548521fa314SDavid van Moolenbroek static const struct flags fd_flags[] = { 549521fa314SDavid van Moolenbroek FLAG(FD_CLOEXEC), 550521fa314SDavid van Moolenbroek }; 551521fa314SDavid van Moolenbroek 552521fa314SDavid van Moolenbroek #define put_fd_flags(p, n, v) \ 553521fa314SDavid van Moolenbroek put_flags(p, n, fd_flags, COUNT(fd_flags), "0x%x", v) 554521fa314SDavid van Moolenbroek 555521fa314SDavid van Moolenbroek static void 556521fa314SDavid van Moolenbroek put_flock_type(struct trace_proc * proc, const char * name, int type) 557521fa314SDavid van Moolenbroek { 558521fa314SDavid van Moolenbroek const char *text = NULL; 559521fa314SDavid van Moolenbroek 560521fa314SDavid van Moolenbroek if (!valuesonly) { 561521fa314SDavid van Moolenbroek switch (type) { 562521fa314SDavid van Moolenbroek TEXT(F_RDLCK); 563521fa314SDavid van Moolenbroek TEXT(F_UNLCK); 564521fa314SDavid van Moolenbroek TEXT(F_WRLCK); 565521fa314SDavid van Moolenbroek } 566521fa314SDavid van Moolenbroek } 567521fa314SDavid van Moolenbroek 568521fa314SDavid van Moolenbroek if (text != NULL) 569521fa314SDavid van Moolenbroek put_field(proc, name, text); 570521fa314SDavid van Moolenbroek else 571521fa314SDavid van Moolenbroek put_value(proc, name, "%d", type); 572521fa314SDavid van Moolenbroek } 573521fa314SDavid van Moolenbroek 574521fa314SDavid van Moolenbroek /* 575521fa314SDavid van Moolenbroek * With PF_FULL, also print l_pid, unless l_type is F_UNLCK in which case 576521fa314SDavid van Moolenbroek * only that type is printed. With PF_ALT, print only l_whence/l_start/l_len. 577521fa314SDavid van Moolenbroek */ 578521fa314SDavid van Moolenbroek static void 579521fa314SDavid van Moolenbroek put_struct_flock(struct trace_proc * proc, const char * name, int flags, 580521fa314SDavid van Moolenbroek vir_bytes addr) 581521fa314SDavid van Moolenbroek { 582521fa314SDavid van Moolenbroek struct flock flock; 583521fa314SDavid van Moolenbroek int limited; 584521fa314SDavid van Moolenbroek 585521fa314SDavid van Moolenbroek if (!put_open_struct(proc, name, flags, addr, &flock, sizeof(flock))) 586521fa314SDavid van Moolenbroek return; 587521fa314SDavid van Moolenbroek 588521fa314SDavid van Moolenbroek limited = ((flags & PF_FULL) && flock.l_type == F_UNLCK); 589521fa314SDavid van Moolenbroek 590521fa314SDavid van Moolenbroek if (!(flags & PF_ALT)) 591521fa314SDavid van Moolenbroek put_flock_type(proc, "l_type", flock.l_type); 592521fa314SDavid van Moolenbroek if (!limited) { 593521fa314SDavid van Moolenbroek put_lseek_whence(proc, "l_whence", flock.l_whence); 594521fa314SDavid van Moolenbroek put_value(proc, "l_start", "%"PRId64, flock.l_start); 595521fa314SDavid van Moolenbroek put_value(proc, "l_len", "%"PRId64, flock.l_len); 596521fa314SDavid van Moolenbroek if (flags & PF_FULL) 597521fa314SDavid van Moolenbroek put_value(proc, "l_pid", "%d", flock.l_pid); 598521fa314SDavid van Moolenbroek } 599521fa314SDavid van Moolenbroek 600521fa314SDavid van Moolenbroek put_close_struct(proc, TRUE /*all*/); 601521fa314SDavid van Moolenbroek } 602521fa314SDavid van Moolenbroek 603521fa314SDavid van Moolenbroek static int 604521fa314SDavid van Moolenbroek vfs_fcntl_out(struct trace_proc * proc, const message * m_out) 605521fa314SDavid van Moolenbroek { 606521fa314SDavid van Moolenbroek 607521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_fcntl.fd); 608521fa314SDavid van Moolenbroek put_fcntl_cmd(proc, "cmd", m_out->m_lc_vfs_fcntl.cmd); 609521fa314SDavid van Moolenbroek 610521fa314SDavid van Moolenbroek switch (m_out->m_lc_vfs_fcntl.cmd) { 611521fa314SDavid van Moolenbroek case F_DUPFD: 612424cad2cSDavid van Moolenbroek case F_DUPFD_CLOEXEC: 613521fa314SDavid van Moolenbroek put_fd(proc, "fd2", m_out->m_lc_vfs_fcntl.arg_int); 614521fa314SDavid van Moolenbroek break; 615521fa314SDavid van Moolenbroek case F_SETFD: 616521fa314SDavid van Moolenbroek put_fd_flags(proc, "flags", m_out->m_lc_vfs_fcntl.arg_int); 617521fa314SDavid van Moolenbroek break; 618521fa314SDavid van Moolenbroek case F_SETFL: 619521fa314SDavid van Moolenbroek /* 620521fa314SDavid van Moolenbroek * One of those difficult cases: the access mode is ignored, so 621521fa314SDavid van Moolenbroek * we don't want to print O_RDONLY if it is not given. On the 622521fa314SDavid van Moolenbroek * other hand, fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_..) is 623521fa314SDavid van Moolenbroek * a fairly common construction, in which case we don't want to 624521fa314SDavid van Moolenbroek * print eg O_..|0x2 if the access mode is O_RDWR. Thus, we 625521fa314SDavid van Moolenbroek * compromise: show the access mode if any of its bits are set. 626521fa314SDavid van Moolenbroek */ 627521fa314SDavid van Moolenbroek put_open_flags(proc, "flags", m_out->m_lc_vfs_fcntl.arg_int, 628521fa314SDavid van Moolenbroek m_out->m_lc_vfs_fcntl.arg_int & O_ACCMODE /*full*/); 629521fa314SDavid van Moolenbroek break; 630521fa314SDavid van Moolenbroek case F_SETLK: 631521fa314SDavid van Moolenbroek case F_SETLKW: 632521fa314SDavid van Moolenbroek put_struct_flock(proc, "lkp", 0, 633521fa314SDavid van Moolenbroek m_out->m_lc_vfs_fcntl.arg_ptr); 634521fa314SDavid van Moolenbroek break; 635521fa314SDavid van Moolenbroek case F_FREESP: 636521fa314SDavid van Moolenbroek put_struct_flock(proc, "lkp", PF_ALT, 637521fa314SDavid van Moolenbroek m_out->m_lc_vfs_fcntl.arg_ptr); 638521fa314SDavid van Moolenbroek break; 639521fa314SDavid van Moolenbroek case F_SETNOSIGPIPE: 640521fa314SDavid van Moolenbroek put_value(proc, "arg", "%d", m_out->m_lc_vfs_fcntl.arg_int); 641521fa314SDavid van Moolenbroek break; 642521fa314SDavid van Moolenbroek } 643521fa314SDavid van Moolenbroek 644521fa314SDavid van Moolenbroek return (m_out->m_lc_vfs_fcntl.cmd != F_GETLK) ? CT_DONE : CT_NOTDONE; 645521fa314SDavid van Moolenbroek } 646521fa314SDavid van Moolenbroek 647521fa314SDavid van Moolenbroek static void 648521fa314SDavid van Moolenbroek vfs_fcntl_in(struct trace_proc * proc, const message * m_out, 649521fa314SDavid van Moolenbroek const message * m_in, int failed) 650521fa314SDavid van Moolenbroek { 651521fa314SDavid van Moolenbroek 652521fa314SDavid van Moolenbroek switch (m_out->m_lc_vfs_fcntl.cmd) { 653521fa314SDavid van Moolenbroek case F_GETFD: 654521fa314SDavid van Moolenbroek if (failed) 655521fa314SDavid van Moolenbroek break; 656521fa314SDavid van Moolenbroek put_fd_flags(proc, NULL, m_in->m_type); 657521fa314SDavid van Moolenbroek return; 658521fa314SDavid van Moolenbroek case F_GETFL: 659521fa314SDavid van Moolenbroek if (failed) 660521fa314SDavid van Moolenbroek break; 661521fa314SDavid van Moolenbroek put_open_flags(proc, NULL, m_in->m_type, TRUE /*full*/); 662521fa314SDavid van Moolenbroek return; 663521fa314SDavid van Moolenbroek case F_GETLK: 664521fa314SDavid van Moolenbroek put_struct_flock(proc, "lkp", failed | PF_FULL, 665521fa314SDavid van Moolenbroek m_out->m_lc_vfs_fcntl.arg_ptr); 666521fa314SDavid van Moolenbroek put_equals(proc); 667521fa314SDavid van Moolenbroek break; 668521fa314SDavid van Moolenbroek } 669521fa314SDavid van Moolenbroek 670521fa314SDavid van Moolenbroek put_result(proc); 671521fa314SDavid van Moolenbroek } 672521fa314SDavid van Moolenbroek 673521fa314SDavid van Moolenbroek static int 674521fa314SDavid van Moolenbroek vfs_pipe2_out(struct trace_proc * __unused proc, 675521fa314SDavid van Moolenbroek const message * __unused m_out) 676521fa314SDavid van Moolenbroek { 677521fa314SDavid van Moolenbroek 678521fa314SDavid van Moolenbroek return CT_NOTDONE; 679521fa314SDavid van Moolenbroek } 680521fa314SDavid van Moolenbroek 681521fa314SDavid van Moolenbroek static void 682521fa314SDavid van Moolenbroek vfs_pipe2_in(struct trace_proc * proc, const message * m_out, 683521fa314SDavid van Moolenbroek const message * m_in, int failed) 684521fa314SDavid van Moolenbroek { 685521fa314SDavid van Moolenbroek 686521fa314SDavid van Moolenbroek if (!failed) { 687521fa314SDavid van Moolenbroek put_open(proc, "fd", PF_NONAME, "[", ", "); 688c33d6ef3SDavid van Moolenbroek put_fd(proc, "rfd", m_in->m_vfs_lc_fdpair.fd0); 689c33d6ef3SDavid van Moolenbroek put_fd(proc, "wfd", m_in->m_vfs_lc_fdpair.fd1); 690521fa314SDavid van Moolenbroek put_close(proc, "]"); 691521fa314SDavid van Moolenbroek } else 692521fa314SDavid van Moolenbroek put_field(proc, "fd", "&.."); 693521fa314SDavid van Moolenbroek put_open_flags(proc, "flags", m_out->m_lc_vfs_pipe2.flags, 694521fa314SDavid van Moolenbroek FALSE /*full*/); 695521fa314SDavid van Moolenbroek put_equals(proc); 696521fa314SDavid van Moolenbroek put_result(proc); 697521fa314SDavid van Moolenbroek } 698521fa314SDavid van Moolenbroek 699521fa314SDavid van Moolenbroek static int 700521fa314SDavid van Moolenbroek vfs_umask_out(struct trace_proc * proc, const message * m_out) 701521fa314SDavid van Moolenbroek { 702521fa314SDavid van Moolenbroek 703521fa314SDavid van Moolenbroek put_mode(proc, NULL, m_out->m_lc_vfs_umask.mask); 704521fa314SDavid van Moolenbroek 705521fa314SDavid van Moolenbroek return CT_DONE; 706521fa314SDavid van Moolenbroek } 707521fa314SDavid van Moolenbroek 708521fa314SDavid van Moolenbroek static void 709521fa314SDavid van Moolenbroek vfs_umask_in(struct trace_proc * proc, const message * __unused m_out, 710521fa314SDavid van Moolenbroek const message * m_in, int failed) 711521fa314SDavid van Moolenbroek { 712521fa314SDavid van Moolenbroek 713521fa314SDavid van Moolenbroek if (!failed) 714521fa314SDavid van Moolenbroek put_mode(proc, NULL, m_in->m_type); 715521fa314SDavid van Moolenbroek else 716521fa314SDavid van Moolenbroek put_result(proc); 717521fa314SDavid van Moolenbroek 718521fa314SDavid van Moolenbroek } 719521fa314SDavid van Moolenbroek 720521fa314SDavid van Moolenbroek static void 721521fa314SDavid van Moolenbroek put_dirent_type(struct trace_proc * proc, const char * name, unsigned int type) 722521fa314SDavid van Moolenbroek { 723521fa314SDavid van Moolenbroek const char *text = NULL; 724521fa314SDavid van Moolenbroek 725521fa314SDavid van Moolenbroek if (!valuesonly) { 726521fa314SDavid van Moolenbroek switch (type) { 727521fa314SDavid van Moolenbroek TEXT(DT_UNKNOWN); 728521fa314SDavid van Moolenbroek TEXT(DT_FIFO); 729521fa314SDavid van Moolenbroek TEXT(DT_CHR); 730521fa314SDavid van Moolenbroek TEXT(DT_DIR); 731521fa314SDavid van Moolenbroek TEXT(DT_BLK); 732521fa314SDavid van Moolenbroek TEXT(DT_REG); 733521fa314SDavid van Moolenbroek TEXT(DT_LNK); 734521fa314SDavid van Moolenbroek TEXT(DT_SOCK); 735521fa314SDavid van Moolenbroek TEXT(DT_WHT); 736521fa314SDavid van Moolenbroek } 737521fa314SDavid van Moolenbroek } 738521fa314SDavid van Moolenbroek 739521fa314SDavid van Moolenbroek if (text != NULL) 740521fa314SDavid van Moolenbroek put_field(proc, name, text); 741521fa314SDavid van Moolenbroek else 742521fa314SDavid van Moolenbroek put_value(proc, name, "%u", type); 743521fa314SDavid van Moolenbroek } 744521fa314SDavid van Moolenbroek 745521fa314SDavid van Moolenbroek static void 746521fa314SDavid van Moolenbroek put_struct_dirent(struct trace_proc * proc, const char *name, int flags, 747521fa314SDavid van Moolenbroek vir_bytes addr) 748521fa314SDavid van Moolenbroek { 749521fa314SDavid van Moolenbroek struct dirent dirent; 750521fa314SDavid van Moolenbroek 751521fa314SDavid van Moolenbroek if (!put_open_struct(proc, name, flags, addr, &dirent, sizeof(dirent))) 752521fa314SDavid van Moolenbroek return; 753521fa314SDavid van Moolenbroek 754521fa314SDavid van Moolenbroek if (verbose > 0) 755521fa314SDavid van Moolenbroek put_value(proc, "d_fileno", "%"PRIu64, dirent.d_fileno); 756521fa314SDavid van Moolenbroek if (verbose > 1) { 757521fa314SDavid van Moolenbroek put_value(proc, "d_reclen", "%u", dirent.d_reclen); 758521fa314SDavid van Moolenbroek put_value(proc, "d_namlen", "%u", dirent.d_namlen); 759521fa314SDavid van Moolenbroek } 760521fa314SDavid van Moolenbroek if (verbose >= 1 + (dirent.d_type == DT_UNKNOWN)) 761521fa314SDavid van Moolenbroek put_dirent_type(proc, "d_type", dirent.d_type); 762521fa314SDavid van Moolenbroek put_buf(proc, "d_name", PF_LOCADDR, (vir_bytes)dirent.d_name, 763521fa314SDavid van Moolenbroek MIN(dirent.d_namlen, sizeof(dirent.d_name))); 764521fa314SDavid van Moolenbroek 765521fa314SDavid van Moolenbroek put_close_struct(proc, verbose > 1); 766521fa314SDavid van Moolenbroek } 767521fa314SDavid van Moolenbroek 768521fa314SDavid van Moolenbroek static void 769521fa314SDavid van Moolenbroek put_dirent_array(struct trace_proc * proc, const char * name, int flags, 770521fa314SDavid van Moolenbroek vir_bytes addr, ssize_t size) 771521fa314SDavid van Moolenbroek { 772521fa314SDavid van Moolenbroek struct dirent dirent; 773521fa314SDavid van Moolenbroek unsigned count, max; 774521fa314SDavid van Moolenbroek ssize_t off, chunk; 775521fa314SDavid van Moolenbroek 776521fa314SDavid van Moolenbroek if ((flags & PF_FAILED) || valuesonly > 1 || size < 0) { 777521fa314SDavid van Moolenbroek put_ptr(proc, name, addr); 778521fa314SDavid van Moolenbroek 779521fa314SDavid van Moolenbroek return; 780521fa314SDavid van Moolenbroek } 781521fa314SDavid van Moolenbroek 782521fa314SDavid van Moolenbroek if (size == 0) { 783521fa314SDavid van Moolenbroek put_field(proc, name, "[]"); 784521fa314SDavid van Moolenbroek 785521fa314SDavid van Moolenbroek return; 786521fa314SDavid van Moolenbroek } 787521fa314SDavid van Moolenbroek 788521fa314SDavid van Moolenbroek if (verbose == 0) 789521fa314SDavid van Moolenbroek max = 0; /* TODO: should we set this to 1 instead? */ 790521fa314SDavid van Moolenbroek else if (verbose == 1) 791521fa314SDavid van Moolenbroek max = 3; /* low; just to give an indication where we are */ 792521fa314SDavid van Moolenbroek else 793521fa314SDavid van Moolenbroek max = INT_MAX; 794521fa314SDavid van Moolenbroek 795521fa314SDavid van Moolenbroek /* 796521fa314SDavid van Moolenbroek * TODO: as is, this is highly inefficient, as we are typically copying 797521fa314SDavid van Moolenbroek * in the same pieces of memory in repeatedly.. 798521fa314SDavid van Moolenbroek */ 799521fa314SDavid van Moolenbroek count = 0; 800521fa314SDavid van Moolenbroek for (off = 0; off < size; off += chunk) { 801521fa314SDavid van Moolenbroek chunk = size - off; 802b58e161cSDavid van Moolenbroek if ((size_t)chunk > sizeof(dirent)) 803b58e161cSDavid van Moolenbroek chunk = (ssize_t)sizeof(dirent); 804b58e161cSDavid van Moolenbroek if ((size_t)chunk < _DIRENT_MINSIZE(&dirent)) 805521fa314SDavid van Moolenbroek break; 806521fa314SDavid van Moolenbroek 807521fa314SDavid van Moolenbroek if (mem_get_data(proc->pid, addr + off, &dirent, chunk) < 0) { 808521fa314SDavid van Moolenbroek if (off == 0) { 809521fa314SDavid van Moolenbroek put_ptr(proc, name, addr); 810521fa314SDavid van Moolenbroek 811521fa314SDavid van Moolenbroek return; 812521fa314SDavid van Moolenbroek } 813521fa314SDavid van Moolenbroek 814521fa314SDavid van Moolenbroek break; 815521fa314SDavid van Moolenbroek } 816521fa314SDavid van Moolenbroek 817521fa314SDavid van Moolenbroek if (off == 0) 818521fa314SDavid van Moolenbroek put_open(proc, name, PF_NONAME, "[", ", "); 819521fa314SDavid van Moolenbroek 820521fa314SDavid van Moolenbroek if (count < max) 821521fa314SDavid van Moolenbroek put_struct_dirent(proc, NULL, PF_LOCADDR, 822521fa314SDavid van Moolenbroek (vir_bytes)&dirent); 823521fa314SDavid van Moolenbroek 824521fa314SDavid van Moolenbroek if (chunk > dirent.d_reclen) 825521fa314SDavid van Moolenbroek chunk = dirent.d_reclen; 826521fa314SDavid van Moolenbroek count++; 827521fa314SDavid van Moolenbroek } 828521fa314SDavid van Moolenbroek 829521fa314SDavid van Moolenbroek if (off < size) 830521fa314SDavid van Moolenbroek put_tail(proc, 0, 0); 831521fa314SDavid van Moolenbroek else if (count > max) 832521fa314SDavid van Moolenbroek put_tail(proc, count, max); 833521fa314SDavid van Moolenbroek put_close(proc, "]"); 834521fa314SDavid van Moolenbroek } 835521fa314SDavid van Moolenbroek 836521fa314SDavid van Moolenbroek static int 837521fa314SDavid van Moolenbroek vfs_getdents_out(struct trace_proc * proc, const message * m_out) 838521fa314SDavid van Moolenbroek { 839521fa314SDavid van Moolenbroek 840521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_readwrite.fd); 841521fa314SDavid van Moolenbroek 842521fa314SDavid van Moolenbroek return CT_NOTDONE; 843521fa314SDavid van Moolenbroek } 844521fa314SDavid van Moolenbroek 845521fa314SDavid van Moolenbroek static void 846521fa314SDavid van Moolenbroek vfs_getdents_in(struct trace_proc * proc, const message * m_out, 847521fa314SDavid van Moolenbroek const message * m_in, int failed) 848521fa314SDavid van Moolenbroek { 849521fa314SDavid van Moolenbroek 850521fa314SDavid van Moolenbroek put_dirent_array(proc, "buf", failed, m_out->m_lc_vfs_readwrite.buf, 851521fa314SDavid van Moolenbroek m_in->m_type); 852521fa314SDavid van Moolenbroek put_value(proc, "len", "%zu", m_out->m_lc_vfs_readwrite.len); 853521fa314SDavid van Moolenbroek put_equals(proc); 854521fa314SDavid van Moolenbroek put_result(proc); 855521fa314SDavid van Moolenbroek } 856521fa314SDavid van Moolenbroek 857521fa314SDavid van Moolenbroek static void 858521fa314SDavid van Moolenbroek put_fd_set(struct trace_proc * proc, const char * name, vir_bytes addr, 859521fa314SDavid van Moolenbroek int nfds) 860521fa314SDavid van Moolenbroek { 861521fa314SDavid van Moolenbroek fd_set set; 862521fa314SDavid van Moolenbroek size_t off; 863521fa314SDavid van Moolenbroek unsigned int i, j, words, count, max; 864521fa314SDavid van Moolenbroek 865521fa314SDavid van Moolenbroek if (addr == 0 || nfds < 0) { 866521fa314SDavid van Moolenbroek put_ptr(proc, name, addr); 867521fa314SDavid van Moolenbroek 868521fa314SDavid van Moolenbroek return; 869521fa314SDavid van Moolenbroek } 870521fa314SDavid van Moolenbroek 871521fa314SDavid van Moolenbroek /* 872521fa314SDavid van Moolenbroek * Each process may define its own FD_SETSIZE, so our fd_set may be of 873521fa314SDavid van Moolenbroek * a different size than theirs. Thus, we copy at a granularity known 874521fa314SDavid van Moolenbroek * to be valid in any case: a single word of bits. We make the 875521fa314SDavid van Moolenbroek * assumption that fd_set consists purely of bits, so that we can use 876521fa314SDavid van Moolenbroek * the second (and so on) bit word as an fd_set by itself. 877521fa314SDavid van Moolenbroek */ 878521fa314SDavid van Moolenbroek words = (nfds + NFDBITS - 1) / NFDBITS; 879521fa314SDavid van Moolenbroek 880521fa314SDavid van Moolenbroek count = 0; 881521fa314SDavid van Moolenbroek 882521fa314SDavid van Moolenbroek if (verbose == 0) 883521fa314SDavid van Moolenbroek max = 16; 884521fa314SDavid van Moolenbroek else if (verbose == 1) 885521fa314SDavid van Moolenbroek max = FD_SETSIZE; 886521fa314SDavid van Moolenbroek else 887521fa314SDavid van Moolenbroek max = INT_MAX; 888521fa314SDavid van Moolenbroek 889521fa314SDavid van Moolenbroek /* TODO: copy in more at once, but stick to fd_mask boundaries. */ 890521fa314SDavid van Moolenbroek for (off = 0, i = 0; i < words; i++, off += sizeof(fd_mask)) { 891521fa314SDavid van Moolenbroek if (mem_get_data(proc->pid, addr + off, &set, 892521fa314SDavid van Moolenbroek sizeof(fd_mask)) != 0) { 893521fa314SDavid van Moolenbroek if (count == 0) { 894521fa314SDavid van Moolenbroek put_ptr(proc, name, addr); 895521fa314SDavid van Moolenbroek 896521fa314SDavid van Moolenbroek return; 897521fa314SDavid van Moolenbroek } 898521fa314SDavid van Moolenbroek 899521fa314SDavid van Moolenbroek break; 900521fa314SDavid van Moolenbroek } 901521fa314SDavid van Moolenbroek 902521fa314SDavid van Moolenbroek for (j = 0; j < NFDBITS; j++) { 903521fa314SDavid van Moolenbroek if (FD_ISSET(j, &set)) { 904521fa314SDavid van Moolenbroek if (count == 0) 905521fa314SDavid van Moolenbroek put_open(proc, name, PF_NONAME, "[", 906521fa314SDavid van Moolenbroek " "); 907521fa314SDavid van Moolenbroek 908521fa314SDavid van Moolenbroek if (count < max) 909521fa314SDavid van Moolenbroek put_fd(proc, NULL, i * NFDBITS + j); 910521fa314SDavid van Moolenbroek 911521fa314SDavid van Moolenbroek count++; 912521fa314SDavid van Moolenbroek } 913521fa314SDavid van Moolenbroek } 914521fa314SDavid van Moolenbroek } 915521fa314SDavid van Moolenbroek 916521fa314SDavid van Moolenbroek /* 917521fa314SDavid van Moolenbroek * The empty set should print as "[]". If copying any part failed, it 918521fa314SDavid van Moolenbroek * should print as "[x, ..(?)]" where x is the set printed so far, if 919521fa314SDavid van Moolenbroek * any. If copying never failed, and we did not print all fds in the 920521fa314SDavid van Moolenbroek * set, print the remaining count n as "[x, ..(+n)]" at the end. 921521fa314SDavid van Moolenbroek */ 922521fa314SDavid van Moolenbroek if (count == 0) 923521fa314SDavid van Moolenbroek put_open(proc, name, PF_NONAME, "[", " "); 924521fa314SDavid van Moolenbroek 925521fa314SDavid van Moolenbroek if (i < words) 926521fa314SDavid van Moolenbroek put_tail(proc, 0, 0); 927521fa314SDavid van Moolenbroek else if (count > max) 928521fa314SDavid van Moolenbroek put_tail(proc, count, max); 929521fa314SDavid van Moolenbroek 930521fa314SDavid van Moolenbroek put_close(proc, "]"); 931521fa314SDavid van Moolenbroek } 932521fa314SDavid van Moolenbroek 933521fa314SDavid van Moolenbroek static int 934521fa314SDavid van Moolenbroek vfs_select_out(struct trace_proc * proc, const message * m_out) 935521fa314SDavid van Moolenbroek { 936521fa314SDavid van Moolenbroek int nfds; 937521fa314SDavid van Moolenbroek 938521fa314SDavid van Moolenbroek nfds = m_out->m_lc_vfs_select.nfds; 939521fa314SDavid van Moolenbroek 940521fa314SDavid van Moolenbroek put_fd(proc, "nfds", nfds); /* not really a file descriptor.. */ 941521fa314SDavid van Moolenbroek put_fd_set(proc, "readfds", 942521fa314SDavid van Moolenbroek (vir_bytes)m_out->m_lc_vfs_select.readfds, nfds); 943521fa314SDavid van Moolenbroek put_fd_set(proc, "writefds", 944521fa314SDavid van Moolenbroek (vir_bytes)m_out->m_lc_vfs_select.writefds, nfds); 945521fa314SDavid van Moolenbroek put_fd_set(proc, "errorfds", 946521fa314SDavid van Moolenbroek (vir_bytes)m_out->m_lc_vfs_select.errorfds, nfds); 947521fa314SDavid van Moolenbroek put_struct_timeval(proc, "timeout", 0, m_out->m_lc_vfs_select.timeout); 948521fa314SDavid van Moolenbroek 949521fa314SDavid van Moolenbroek return CT_DONE; 950521fa314SDavid van Moolenbroek } 951521fa314SDavid van Moolenbroek 952521fa314SDavid van Moolenbroek static void 953521fa314SDavid van Moolenbroek vfs_select_in(struct trace_proc * proc, const message * m_out, 954521fa314SDavid van Moolenbroek const message * __unused m_in, int failed) 955521fa314SDavid van Moolenbroek { 956521fa314SDavid van Moolenbroek vir_bytes readfds, writefds, errorfds; 957521fa314SDavid van Moolenbroek int nfds; 958521fa314SDavid van Moolenbroek 959521fa314SDavid van Moolenbroek put_result(proc); 960521fa314SDavid van Moolenbroek if (failed) 961521fa314SDavid van Moolenbroek return; 962521fa314SDavid van Moolenbroek 963521fa314SDavid van Moolenbroek nfds = m_out->m_lc_vfs_select.nfds; 964521fa314SDavid van Moolenbroek 965521fa314SDavid van Moolenbroek readfds = (vir_bytes)m_out->m_lc_vfs_select.readfds; 966521fa314SDavid van Moolenbroek writefds = (vir_bytes)m_out->m_lc_vfs_select.writefds; 967521fa314SDavid van Moolenbroek errorfds = (vir_bytes)m_out->m_lc_vfs_select.errorfds; 968521fa314SDavid van Moolenbroek 969521fa314SDavid van Moolenbroek if (readfds == 0 && writefds == 0 && errorfds == 0) 970521fa314SDavid van Moolenbroek return; 971521fa314SDavid van Moolenbroek 972521fa314SDavid van Moolenbroek /* Omit names, because it looks weird. */ 973521fa314SDavid van Moolenbroek put_open(proc, NULL, PF_NONAME, "(", ", "); 974521fa314SDavid van Moolenbroek if (readfds != 0) 975521fa314SDavid van Moolenbroek put_fd_set(proc, "readfds", readfds, nfds); 976521fa314SDavid van Moolenbroek if (writefds != 0) 977521fa314SDavid van Moolenbroek put_fd_set(proc, "writefds", writefds, nfds); 978521fa314SDavid van Moolenbroek if (errorfds != 0) 979521fa314SDavid van Moolenbroek put_fd_set(proc, "errorfds", errorfds, nfds); 980521fa314SDavid van Moolenbroek put_close(proc, ")"); 981521fa314SDavid van Moolenbroek } 982521fa314SDavid van Moolenbroek 983521fa314SDavid van Moolenbroek static int 984521fa314SDavid van Moolenbroek vfs_fchdir_out(struct trace_proc * proc, const message * m_out) 985521fa314SDavid van Moolenbroek { 986521fa314SDavid van Moolenbroek 987521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_fchdir.fd); 988521fa314SDavid van Moolenbroek 989521fa314SDavid van Moolenbroek return CT_DONE; 990521fa314SDavid van Moolenbroek } 991521fa314SDavid van Moolenbroek 992521fa314SDavid van Moolenbroek static int 993521fa314SDavid van Moolenbroek vfs_fsync_out(struct trace_proc * proc, const message * m_out) 994521fa314SDavid van Moolenbroek { 995521fa314SDavid van Moolenbroek 996521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_fsync.fd); 997521fa314SDavid van Moolenbroek 998521fa314SDavid van Moolenbroek return CT_DONE; 999521fa314SDavid van Moolenbroek } 1000521fa314SDavid van Moolenbroek 1001521fa314SDavid van Moolenbroek static int 1002521fa314SDavid van Moolenbroek vfs_truncate_out(struct trace_proc * proc, const message * m_out) 1003521fa314SDavid van Moolenbroek { 1004521fa314SDavid van Moolenbroek 1005521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_truncate.name, 1006521fa314SDavid van Moolenbroek m_out->m_lc_vfs_truncate.len); 1007521fa314SDavid van Moolenbroek put_value(proc, "length", "%"PRId64, m_out->m_lc_vfs_truncate.offset); 1008521fa314SDavid van Moolenbroek 1009521fa314SDavid van Moolenbroek return CT_DONE; 1010521fa314SDavid van Moolenbroek } 1011521fa314SDavid van Moolenbroek 1012521fa314SDavid van Moolenbroek static int 1013521fa314SDavid van Moolenbroek vfs_ftruncate_out(struct trace_proc * proc, const message * m_out) 1014521fa314SDavid van Moolenbroek { 1015521fa314SDavid van Moolenbroek 1016521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_truncate.fd); 1017521fa314SDavid van Moolenbroek put_value(proc, "length", "%"PRId64, m_out->m_lc_vfs_truncate.offset); 1018521fa314SDavid van Moolenbroek 1019521fa314SDavid van Moolenbroek return CT_DONE; 1020521fa314SDavid van Moolenbroek } 1021521fa314SDavid van Moolenbroek 1022521fa314SDavid van Moolenbroek static int 1023521fa314SDavid van Moolenbroek vfs_fchmod_out(struct trace_proc * proc, const message * m_out) 1024521fa314SDavid van Moolenbroek { 1025521fa314SDavid van Moolenbroek 1026521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_fchmod.fd); 1027521fa314SDavid van Moolenbroek put_mode(proc, "mode", m_out->m_lc_vfs_fchmod.mode); 1028521fa314SDavid van Moolenbroek 1029521fa314SDavid van Moolenbroek return CT_DONE; 1030521fa314SDavid van Moolenbroek } 1031521fa314SDavid van Moolenbroek 1032521fa314SDavid van Moolenbroek static int 1033521fa314SDavid van Moolenbroek vfs_fchown_out(struct trace_proc * proc, const message * m_out) 1034521fa314SDavid van Moolenbroek { 1035521fa314SDavid van Moolenbroek 1036521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_chown.fd); 1037521fa314SDavid van Moolenbroek /* -1 means "keep the current value" so print as signed */ 1038521fa314SDavid van Moolenbroek put_value(proc, "owner", "%d", m_out->m_lc_vfs_chown.owner); 1039521fa314SDavid van Moolenbroek put_value(proc, "group", "%d", m_out->m_lc_vfs_chown.group); 1040521fa314SDavid van Moolenbroek 1041521fa314SDavid van Moolenbroek return CT_DONE; 1042521fa314SDavid van Moolenbroek } 1043521fa314SDavid van Moolenbroek 1044521fa314SDavid van Moolenbroek static const char * 1045521fa314SDavid van Moolenbroek vfs_utimens_name(const message * m_out) 1046521fa314SDavid van Moolenbroek { 1047521fa314SDavid van Moolenbroek int has_path, has_flags; 1048521fa314SDavid van Moolenbroek 1049521fa314SDavid van Moolenbroek has_path = (m_out->m_vfs_utimens.name != NULL); 1050521fa314SDavid van Moolenbroek has_flags = (m_out->m_vfs_utimens.flags != 0); 1051521fa314SDavid van Moolenbroek 1052521fa314SDavid van Moolenbroek if (has_path && m_out->m_vfs_utimens.flags == AT_SYMLINK_NOFOLLOW) 1053521fa314SDavid van Moolenbroek return "lutimens"; 1054521fa314SDavid van Moolenbroek if (has_path && !has_flags) 1055521fa314SDavid van Moolenbroek return "utimens"; 1056521fa314SDavid van Moolenbroek else if (!has_path && !has_flags) 1057521fa314SDavid van Moolenbroek return "futimens"; 1058521fa314SDavid van Moolenbroek else 1059521fa314SDavid van Moolenbroek return "utimensat"; 1060521fa314SDavid van Moolenbroek } 1061521fa314SDavid van Moolenbroek 1062521fa314SDavid van Moolenbroek static const struct flags at_flags[] = { 1063521fa314SDavid van Moolenbroek FLAG(AT_EACCESS), 1064521fa314SDavid van Moolenbroek FLAG(AT_SYMLINK_NOFOLLOW), 1065521fa314SDavid van Moolenbroek FLAG(AT_SYMLINK_FOLLOW), 1066521fa314SDavid van Moolenbroek FLAG(AT_REMOVEDIR), 1067521fa314SDavid van Moolenbroek }; 1068521fa314SDavid van Moolenbroek 1069521fa314SDavid van Moolenbroek static void 1070521fa314SDavid van Moolenbroek put_utimens_timespec(struct trace_proc * proc, const char * name, 1071521fa314SDavid van Moolenbroek time_t sec, long nsec) 1072521fa314SDavid van Moolenbroek { 1073521fa314SDavid van Moolenbroek 1074521fa314SDavid van Moolenbroek /* No field names. */ 1075521fa314SDavid van Moolenbroek put_open(proc, name, PF_NONAME, "{", ", "); 1076521fa314SDavid van Moolenbroek 1077521fa314SDavid van Moolenbroek put_time(proc, "tv_sec", sec); 1078521fa314SDavid van Moolenbroek 1079521fa314SDavid van Moolenbroek if (!valuesonly && nsec == UTIME_NOW) 1080521fa314SDavid van Moolenbroek put_field(proc, "tv_nsec", "UTIME_NOW"); 1081521fa314SDavid van Moolenbroek else if (!valuesonly && nsec == UTIME_OMIT) 1082521fa314SDavid van Moolenbroek put_field(proc, "tv_nsec", "UTIME_OMIT"); 1083521fa314SDavid van Moolenbroek else 1084521fa314SDavid van Moolenbroek put_value(proc, "tv_nsec", "%ld", nsec); 1085521fa314SDavid van Moolenbroek 1086521fa314SDavid van Moolenbroek put_close(proc, "}"); 1087521fa314SDavid van Moolenbroek } 1088521fa314SDavid van Moolenbroek 1089521fa314SDavid van Moolenbroek static int 1090521fa314SDavid van Moolenbroek vfs_utimens_out(struct trace_proc * proc, const message * m_out) 1091521fa314SDavid van Moolenbroek { 1092521fa314SDavid van Moolenbroek int has_path, has_flags; 1093521fa314SDavid van Moolenbroek 1094521fa314SDavid van Moolenbroek /* Here we do not care about the utimens/lutimens distinction. */ 1095521fa314SDavid van Moolenbroek has_path = (m_out->m_vfs_utimens.name != NULL); 1096521fa314SDavid van Moolenbroek has_flags = !!(m_out->m_vfs_utimens.flags & ~AT_SYMLINK_NOFOLLOW); 1097521fa314SDavid van Moolenbroek 1098521fa314SDavid van Moolenbroek if (has_path && has_flags) 1099521fa314SDavid van Moolenbroek put_field(proc, "fd", "AT_CWD"); /* utimensat */ 1100521fa314SDavid van Moolenbroek else if (!has_path) 1101521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_vfs_utimens.fd); /* futimes */ 1102521fa314SDavid van Moolenbroek if (has_path || has_flags) /* lutimes, utimes, utimensat */ 1103521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, 1104521fa314SDavid van Moolenbroek (vir_bytes)m_out->m_vfs_utimens.name, 1105521fa314SDavid van Moolenbroek m_out->m_vfs_utimens.len); 1106521fa314SDavid van Moolenbroek 1107521fa314SDavid van Moolenbroek put_open(proc, "times", 0, "[", ", "); 1108521fa314SDavid van Moolenbroek put_utimens_timespec(proc, "atime", m_out->m_vfs_utimens.atime, 1109521fa314SDavid van Moolenbroek m_out->m_vfs_utimens.ansec); 1110521fa314SDavid van Moolenbroek put_utimens_timespec(proc, "mtime", m_out->m_vfs_utimens.mtime, 1111521fa314SDavid van Moolenbroek m_out->m_vfs_utimens.mnsec); 1112521fa314SDavid van Moolenbroek put_close(proc, "]"); 1113521fa314SDavid van Moolenbroek 1114521fa314SDavid van Moolenbroek if (has_flags) 1115521fa314SDavid van Moolenbroek put_flags(proc, "flag", at_flags, COUNT(at_flags), "0x%x", 1116521fa314SDavid van Moolenbroek m_out->m_vfs_utimens.flags); 1117521fa314SDavid van Moolenbroek 1118521fa314SDavid van Moolenbroek return CT_DONE; 1119521fa314SDavid van Moolenbroek } 1120521fa314SDavid van Moolenbroek 1121521fa314SDavid van Moolenbroek static const struct flags statvfs_flags[] = { 1122521fa314SDavid van Moolenbroek FLAG(ST_WAIT), 1123521fa314SDavid van Moolenbroek FLAG(ST_NOWAIT), 1124521fa314SDavid van Moolenbroek }; 1125521fa314SDavid van Moolenbroek 1126521fa314SDavid van Moolenbroek static const struct flags st_flags[] = { 1127521fa314SDavid van Moolenbroek FLAG(ST_RDONLY), 1128521fa314SDavid van Moolenbroek FLAG(ST_SYNCHRONOUS), 1129521fa314SDavid van Moolenbroek FLAG(ST_NOEXEC), 1130521fa314SDavid van Moolenbroek FLAG(ST_NOSUID), 1131521fa314SDavid van Moolenbroek FLAG(ST_NODEV), 1132521fa314SDavid van Moolenbroek FLAG(ST_UNION), 1133521fa314SDavid van Moolenbroek FLAG(ST_ASYNC), 1134521fa314SDavid van Moolenbroek FLAG(ST_NOCOREDUMP), 1135521fa314SDavid van Moolenbroek FLAG(ST_RELATIME), 1136521fa314SDavid van Moolenbroek FLAG(ST_IGNORE), 1137521fa314SDavid van Moolenbroek FLAG(ST_NOATIME), 1138521fa314SDavid van Moolenbroek FLAG(ST_SYMPERM), 1139521fa314SDavid van Moolenbroek FLAG(ST_NODEVMTIME), 1140521fa314SDavid van Moolenbroek FLAG(ST_SOFTDEP), 1141521fa314SDavid van Moolenbroek FLAG(ST_LOG), 1142521fa314SDavid van Moolenbroek FLAG(ST_EXTATTR), 1143521fa314SDavid van Moolenbroek FLAG(ST_EXRDONLY), 1144521fa314SDavid van Moolenbroek FLAG(ST_EXPORTED), 1145521fa314SDavid van Moolenbroek FLAG(ST_DEFEXPORTED), 1146521fa314SDavid van Moolenbroek FLAG(ST_EXPORTANON), 1147521fa314SDavid van Moolenbroek FLAG(ST_EXKERB), 1148521fa314SDavid van Moolenbroek FLAG(ST_EXNORESPORT), 1149521fa314SDavid van Moolenbroek FLAG(ST_EXPUBLIC), 1150521fa314SDavid van Moolenbroek FLAG(ST_LOCAL), 1151521fa314SDavid van Moolenbroek FLAG(ST_QUOTA), 1152521fa314SDavid van Moolenbroek FLAG(ST_ROOTFS), 1153521fa314SDavid van Moolenbroek FLAG(ST_NOTRUNC), 1154521fa314SDavid van Moolenbroek }; 1155521fa314SDavid van Moolenbroek 1156521fa314SDavid van Moolenbroek static void 1157521fa314SDavid van Moolenbroek put_struct_statvfs(struct trace_proc * proc, const char * name, int flags, 1158521fa314SDavid van Moolenbroek vir_bytes addr) 1159521fa314SDavid van Moolenbroek { 1160521fa314SDavid van Moolenbroek struct statvfs buf; 1161521fa314SDavid van Moolenbroek 1162521fa314SDavid van Moolenbroek if (!put_open_struct(proc, name, flags, addr, &buf, sizeof(buf))) 1163521fa314SDavid van Moolenbroek return; 1164521fa314SDavid van Moolenbroek 1165521fa314SDavid van Moolenbroek put_flags(proc, "f_flag", st_flags, COUNT(st_flags), "0x%x", 1166521fa314SDavid van Moolenbroek buf.f_flag); 1167521fa314SDavid van Moolenbroek put_value(proc, "f_bsize", "%lu", buf.f_bsize); 1168521fa314SDavid van Moolenbroek if (verbose > 0 || buf.f_bsize != buf.f_frsize) 1169521fa314SDavid van Moolenbroek put_value(proc, "f_frsize", "%lu", buf.f_frsize); 1170521fa314SDavid van Moolenbroek if (verbose > 1) 1171521fa314SDavid van Moolenbroek put_value(proc, "f_iosize", "%lu", buf.f_iosize); 1172521fa314SDavid van Moolenbroek 1173521fa314SDavid van Moolenbroek put_value(proc, "f_blocks", "%"PRIu64, buf.f_blocks); 1174521fa314SDavid van Moolenbroek put_value(proc, "f_bfree", "%"PRIu64, buf.f_bfree); 1175521fa314SDavid van Moolenbroek if (verbose > 1) { 1176521fa314SDavid van Moolenbroek put_value(proc, "f_bavail", "%"PRIu64, buf.f_bavail); 1177521fa314SDavid van Moolenbroek put_value(proc, "f_bresvd", "%"PRIu64, buf.f_bresvd); 1178521fa314SDavid van Moolenbroek } 1179521fa314SDavid van Moolenbroek 1180521fa314SDavid van Moolenbroek if (verbose > 0) { 1181521fa314SDavid van Moolenbroek put_value(proc, "f_files", "%"PRIu64, buf.f_files); 1182521fa314SDavid van Moolenbroek put_value(proc, "f_ffree", "%"PRIu64, buf.f_ffree); 1183521fa314SDavid van Moolenbroek } 1184521fa314SDavid van Moolenbroek if (verbose > 1) { 1185521fa314SDavid van Moolenbroek put_value(proc, "f_favail", "%"PRIu64, buf.f_favail); 1186521fa314SDavid van Moolenbroek put_value(proc, "f_fresvd", "%"PRIu64, buf.f_fresvd); 1187521fa314SDavid van Moolenbroek } 1188521fa314SDavid van Moolenbroek 1189521fa314SDavid van Moolenbroek if (verbose > 1) { 1190521fa314SDavid van Moolenbroek put_value(proc, "f_syncreads", "%"PRIu64, buf.f_syncreads); 1191521fa314SDavid van Moolenbroek put_value(proc, "f_syncwrites", "%"PRIu64, buf.f_syncwrites); 1192521fa314SDavid van Moolenbroek put_value(proc, "f_asyncreads", "%"PRIu64, buf.f_asyncreads); 1193521fa314SDavid van Moolenbroek put_value(proc, "f_asyncwrites", "%"PRIu64, buf.f_asyncwrites); 1194521fa314SDavid van Moolenbroek 1195521fa314SDavid van Moolenbroek put_value(proc, "f_fsidx", "<%"PRId32",%"PRId32">", 1196521fa314SDavid van Moolenbroek buf.f_fsidx.__fsid_val[0], buf.f_fsidx.__fsid_val[1]); 1197521fa314SDavid van Moolenbroek } 1198521fa314SDavid van Moolenbroek put_dev(proc, "f_fsid", buf.f_fsid); /* MINIX3 interpretation! */ 1199521fa314SDavid van Moolenbroek 1200521fa314SDavid van Moolenbroek if (verbose > 0) 1201521fa314SDavid van Moolenbroek put_value(proc, "f_namemax", "%lu", buf.f_namemax); 1202521fa314SDavid van Moolenbroek if (verbose > 1) 1203521fa314SDavid van Moolenbroek put_value(proc, "f_owner", "%u", buf.f_owner); 1204521fa314SDavid van Moolenbroek 1205521fa314SDavid van Moolenbroek put_buf(proc, "f_fstypename", PF_STRING | PF_LOCADDR, 1206521fa314SDavid van Moolenbroek (vir_bytes)&buf.f_fstypename, sizeof(buf.f_fstypename)); 1207521fa314SDavid van Moolenbroek if (verbose > 0) 1208521fa314SDavid van Moolenbroek put_buf(proc, "f_mntfromname", PF_STRING | PF_LOCADDR, 1209521fa314SDavid van Moolenbroek (vir_bytes)&buf.f_mntfromname, sizeof(buf.f_mntfromname)); 1210521fa314SDavid van Moolenbroek put_buf(proc, "f_mntonname", PF_STRING | PF_LOCADDR, 1211521fa314SDavid van Moolenbroek (vir_bytes)&buf.f_mntonname, sizeof(buf.f_mntonname)); 1212521fa314SDavid van Moolenbroek 1213521fa314SDavid van Moolenbroek put_close_struct(proc, verbose > 1); 1214521fa314SDavid van Moolenbroek } 1215521fa314SDavid van Moolenbroek 1216521fa314SDavid van Moolenbroek static void 1217521fa314SDavid van Moolenbroek put_statvfs_array(struct trace_proc * proc, const char * name, int flags, 1218521fa314SDavid van Moolenbroek vir_bytes addr, int count) 1219521fa314SDavid van Moolenbroek { 1220521fa314SDavid van Moolenbroek struct statvfs buf; 1221521fa314SDavid van Moolenbroek int i, max; 1222521fa314SDavid van Moolenbroek 1223c38dbb97SDavid van Moolenbroek if ((flags & PF_FAILED) || valuesonly > 1 || count < 0) { 1224521fa314SDavid van Moolenbroek put_ptr(proc, name, addr); 1225521fa314SDavid van Moolenbroek 1226521fa314SDavid van Moolenbroek return; 1227521fa314SDavid van Moolenbroek } 1228521fa314SDavid van Moolenbroek 1229521fa314SDavid van Moolenbroek if (count == 0) { 1230521fa314SDavid van Moolenbroek put_field(proc, name, "[]"); 1231521fa314SDavid van Moolenbroek 1232521fa314SDavid van Moolenbroek return; 1233521fa314SDavid van Moolenbroek } 1234521fa314SDavid van Moolenbroek 1235521fa314SDavid van Moolenbroek if (verbose == 0) 1236521fa314SDavid van Moolenbroek max = 0; 1237521fa314SDavid van Moolenbroek else if (verbose == 1) 1238521fa314SDavid van Moolenbroek max = 1; /* TODO: is this reasonable? */ 1239521fa314SDavid van Moolenbroek else 1240521fa314SDavid van Moolenbroek max = INT_MAX; 1241521fa314SDavid van Moolenbroek 1242521fa314SDavid van Moolenbroek if (max > count) 1243521fa314SDavid van Moolenbroek max = count; 1244521fa314SDavid van Moolenbroek 1245521fa314SDavid van Moolenbroek for (i = 0; i < max; i++) { 1246521fa314SDavid van Moolenbroek if (mem_get_data(proc->pid, addr + i * sizeof(buf), &buf, 1247521fa314SDavid van Moolenbroek sizeof(buf)) < 0) { 1248521fa314SDavid van Moolenbroek if (i == 0) { 1249521fa314SDavid van Moolenbroek put_ptr(proc, name, addr); 1250521fa314SDavid van Moolenbroek 1251521fa314SDavid van Moolenbroek return; 1252521fa314SDavid van Moolenbroek } 1253521fa314SDavid van Moolenbroek 1254521fa314SDavid van Moolenbroek break; 1255521fa314SDavid van Moolenbroek } 1256521fa314SDavid van Moolenbroek 1257521fa314SDavid van Moolenbroek if (i == 0) 1258521fa314SDavid van Moolenbroek put_open(proc, name, PF_NONAME, "[", ", "); 1259521fa314SDavid van Moolenbroek 1260521fa314SDavid van Moolenbroek put_struct_statvfs(proc, NULL, PF_LOCADDR, (vir_bytes)&buf); 1261521fa314SDavid van Moolenbroek } 1262521fa314SDavid van Moolenbroek 1263521fa314SDavid van Moolenbroek if (i == 0) 1264521fa314SDavid van Moolenbroek put_open(proc, name, PF_NONAME, "[", ", "); 1265521fa314SDavid van Moolenbroek if (i < max) 1266521fa314SDavid van Moolenbroek put_tail(proc, 0, 0); 1267521fa314SDavid van Moolenbroek else if (count > i) 1268521fa314SDavid van Moolenbroek put_tail(proc, count, i); 1269521fa314SDavid van Moolenbroek put_close(proc, "]"); 1270521fa314SDavid van Moolenbroek } 1271521fa314SDavid van Moolenbroek 1272521fa314SDavid van Moolenbroek static int 1273521fa314SDavid van Moolenbroek vfs_getvfsstat_out(struct trace_proc * proc, const message * m_out) 1274521fa314SDavid van Moolenbroek { 1275521fa314SDavid van Moolenbroek 1276521fa314SDavid van Moolenbroek if (m_out->m_lc_vfs_getvfsstat.buf == 0) { 1277521fa314SDavid van Moolenbroek put_ptr(proc, "buf", m_out->m_lc_vfs_getvfsstat.buf); 1278521fa314SDavid van Moolenbroek put_value(proc, "bufsize", "%zu", 1279521fa314SDavid van Moolenbroek m_out->m_lc_vfs_getvfsstat.len); 1280521fa314SDavid van Moolenbroek put_flags(proc, "flags", statvfs_flags, COUNT(statvfs_flags), 1281521fa314SDavid van Moolenbroek "%d", m_out->m_lc_vfs_getvfsstat.flags); 1282521fa314SDavid van Moolenbroek return CT_DONE; 1283521fa314SDavid van Moolenbroek } else 1284521fa314SDavid van Moolenbroek return CT_NOTDONE; 1285521fa314SDavid van Moolenbroek } 1286521fa314SDavid van Moolenbroek 1287521fa314SDavid van Moolenbroek static void 1288521fa314SDavid van Moolenbroek vfs_getvfsstat_in(struct trace_proc * proc, const message * m_out, 1289521fa314SDavid van Moolenbroek const message * m_in, int failed) 1290521fa314SDavid van Moolenbroek { 1291521fa314SDavid van Moolenbroek 1292521fa314SDavid van Moolenbroek if (m_out->m_lc_vfs_getvfsstat.buf != 0) { 1293521fa314SDavid van Moolenbroek put_statvfs_array(proc, "buf", failed, 1294521fa314SDavid van Moolenbroek m_out->m_lc_vfs_getvfsstat.buf, m_in->m_type); 1295521fa314SDavid van Moolenbroek put_value(proc, "bufsize", "%zu", 1296521fa314SDavid van Moolenbroek m_out->m_lc_vfs_getvfsstat.len); 1297521fa314SDavid van Moolenbroek put_flags(proc, "flags", statvfs_flags, COUNT(statvfs_flags), 1298521fa314SDavid van Moolenbroek "%d", m_out->m_lc_vfs_getvfsstat.flags); 1299521fa314SDavid van Moolenbroek put_equals(proc); 1300521fa314SDavid van Moolenbroek } 1301521fa314SDavid van Moolenbroek put_result(proc); 1302521fa314SDavid van Moolenbroek } 1303521fa314SDavid van Moolenbroek 1304521fa314SDavid van Moolenbroek static int 1305521fa314SDavid van Moolenbroek vfs_statvfs1_out(struct trace_proc * proc, const message * m_out) 1306521fa314SDavid van Moolenbroek { 1307521fa314SDavid van Moolenbroek 1308521fa314SDavid van Moolenbroek put_buf(proc, "path", PF_PATH, m_out->m_lc_vfs_statvfs1.name, 1309521fa314SDavid van Moolenbroek m_out->m_lc_vfs_statvfs1.len); 1310521fa314SDavid van Moolenbroek 1311521fa314SDavid van Moolenbroek return CT_NOTDONE; 1312521fa314SDavid van Moolenbroek } 1313521fa314SDavid van Moolenbroek 1314521fa314SDavid van Moolenbroek static void 1315521fa314SDavid van Moolenbroek vfs_statvfs1_in(struct trace_proc * proc, const message * m_out, 1316521fa314SDavid van Moolenbroek const message * __unused m_in, int failed) 1317521fa314SDavid van Moolenbroek { 1318521fa314SDavid van Moolenbroek 1319521fa314SDavid van Moolenbroek put_struct_statvfs(proc, "buf", failed, m_out->m_lc_vfs_statvfs1.buf); 1320521fa314SDavid van Moolenbroek put_flags(proc, "flags", statvfs_flags, COUNT(statvfs_flags), "%d", 1321521fa314SDavid van Moolenbroek m_out->m_lc_vfs_statvfs1.flags); 1322521fa314SDavid van Moolenbroek put_equals(proc); 1323521fa314SDavid van Moolenbroek put_result(proc); 1324521fa314SDavid van Moolenbroek } 1325521fa314SDavid van Moolenbroek 1326521fa314SDavid van Moolenbroek /* This function is shared between statvfs1 and fstatvfs1. */ 1327521fa314SDavid van Moolenbroek static int 1328521fa314SDavid van Moolenbroek vfs_fstatvfs1_out(struct trace_proc * proc, const message * m_out) 1329521fa314SDavid van Moolenbroek { 1330521fa314SDavid van Moolenbroek 1331521fa314SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_statvfs1.fd); 1332521fa314SDavid van Moolenbroek 1333521fa314SDavid van Moolenbroek return CT_NOTDONE; 1334521fa314SDavid van Moolenbroek } 1335521fa314SDavid van Moolenbroek 1336521fa314SDavid van Moolenbroek static int 1337521fa314SDavid van Moolenbroek vfs_svrctl_out(struct trace_proc * proc, const message * m_out) 1338521fa314SDavid van Moolenbroek { 1339521fa314SDavid van Moolenbroek 1340521fa314SDavid van Moolenbroek put_ioctl_req(proc, "request", m_out->m_lc_svrctl.request, 1341521fa314SDavid van Moolenbroek TRUE /*is_svrctl*/); 1342521fa314SDavid van Moolenbroek return put_ioctl_arg_out(proc, "arg", m_out->m_lc_svrctl.request, 1343521fa314SDavid van Moolenbroek m_out->m_lc_svrctl.arg, TRUE /*is_svrctl*/); 1344521fa314SDavid van Moolenbroek } 1345521fa314SDavid van Moolenbroek 1346521fa314SDavid van Moolenbroek static void 1347521fa314SDavid van Moolenbroek vfs_svrctl_in(struct trace_proc * proc, const message * m_out, 1348521fa314SDavid van Moolenbroek const message * __unused m_in, int failed) 1349521fa314SDavid van Moolenbroek { 1350521fa314SDavid van Moolenbroek 1351521fa314SDavid van Moolenbroek put_ioctl_arg_in(proc, "arg", failed, m_out->m_lc_svrctl.request, 1352521fa314SDavid van Moolenbroek m_out->m_lc_svrctl.arg, TRUE /*is_svrctl*/); 1353521fa314SDavid van Moolenbroek } 1354521fa314SDavid van Moolenbroek 1355521fa314SDavid van Moolenbroek static int 1356521fa314SDavid van Moolenbroek vfs_gcov_flush_out(struct trace_proc * proc, const message * m_out) 1357521fa314SDavid van Moolenbroek { 1358521fa314SDavid van Moolenbroek 13593ac58492SDavid van Moolenbroek put_buf(proc, "label", PF_STRING, m_out->m_lc_vfs_gcov.label, 13603ac58492SDavid van Moolenbroek m_out->m_lc_vfs_gcov.labellen); 13613ac58492SDavid van Moolenbroek put_ptr(proc, "buff", m_out->m_lc_vfs_gcov.buf); 13623ac58492SDavid van Moolenbroek put_value(proc, "buff_sz", "%zu", m_out->m_lc_vfs_gcov.buflen); 1363521fa314SDavid van Moolenbroek 1364521fa314SDavid van Moolenbroek return CT_DONE; 1365521fa314SDavid van Moolenbroek } 1366521fa314SDavid van Moolenbroek 1367c38dbb97SDavid van Moolenbroek void 1368c38dbb97SDavid van Moolenbroek put_socket_family(struct trace_proc * proc, const char * name, int family) 1369c38dbb97SDavid van Moolenbroek { 1370c38dbb97SDavid van Moolenbroek const char *text = NULL; 1371c38dbb97SDavid van Moolenbroek 1372c38dbb97SDavid van Moolenbroek if (!valuesonly) { 1373c38dbb97SDavid van Moolenbroek /* 1374c38dbb97SDavid van Moolenbroek * For socket(2) and socketpair(2) this should really be using 1375c38dbb97SDavid van Moolenbroek * the prefix "PF_" since those functions take a protocol 1376c38dbb97SDavid van Moolenbroek * family rather than an address family. This rule is applied 1377c38dbb97SDavid van Moolenbroek * fairly consistently within the system. Here I caved because 1378c38dbb97SDavid van Moolenbroek * I don't want to duplicate this entire function just for the 1379c38dbb97SDavid van Moolenbroek * one letter. There are exceptions however; some names only 1380c38dbb97SDavid van Moolenbroek * exist as "PF_". 1381c38dbb97SDavid van Moolenbroek */ 1382c38dbb97SDavid van Moolenbroek switch (family) { 1383c38dbb97SDavid van Moolenbroek TEXT(AF_UNSPEC); 1384c38dbb97SDavid van Moolenbroek TEXT(AF_LOCAL); 1385c38dbb97SDavid van Moolenbroek TEXT(AF_INET); 1386c38dbb97SDavid van Moolenbroek TEXT(AF_IMPLINK); 1387c38dbb97SDavid van Moolenbroek TEXT(AF_PUP); 1388c38dbb97SDavid van Moolenbroek TEXT(AF_CHAOS); 1389c38dbb97SDavid van Moolenbroek TEXT(AF_NS); 1390c38dbb97SDavid van Moolenbroek TEXT(AF_ISO); 1391c38dbb97SDavid van Moolenbroek TEXT(AF_ECMA); 1392c38dbb97SDavid van Moolenbroek TEXT(AF_DATAKIT); 1393c38dbb97SDavid van Moolenbroek TEXT(AF_CCITT); 1394c38dbb97SDavid van Moolenbroek TEXT(AF_SNA); 1395c38dbb97SDavid van Moolenbroek TEXT(AF_DECnet); 1396c38dbb97SDavid van Moolenbroek TEXT(AF_DLI); 1397c38dbb97SDavid van Moolenbroek TEXT(AF_LAT); 1398c38dbb97SDavid van Moolenbroek TEXT(AF_HYLINK); 1399c38dbb97SDavid van Moolenbroek TEXT(AF_APPLETALK); 1400c38dbb97SDavid van Moolenbroek TEXT(AF_OROUTE); 1401c38dbb97SDavid van Moolenbroek TEXT(AF_LINK); 1402c38dbb97SDavid van Moolenbroek TEXT(PF_XTP); 1403c38dbb97SDavid van Moolenbroek TEXT(AF_COIP); 1404c38dbb97SDavid van Moolenbroek TEXT(AF_CNT); 1405c38dbb97SDavid van Moolenbroek TEXT(PF_RTIP); 1406c38dbb97SDavid van Moolenbroek TEXT(AF_IPX); 1407c38dbb97SDavid van Moolenbroek TEXT(AF_INET6); 1408c38dbb97SDavid van Moolenbroek TEXT(PF_PIP); 1409c38dbb97SDavid van Moolenbroek TEXT(AF_ISDN); 1410c38dbb97SDavid van Moolenbroek TEXT(AF_NATM); 1411c38dbb97SDavid van Moolenbroek TEXT(AF_ARP); 1412c38dbb97SDavid van Moolenbroek TEXT(PF_KEY); 1413c38dbb97SDavid van Moolenbroek TEXT(AF_BLUETOOTH); 1414c38dbb97SDavid van Moolenbroek TEXT(AF_IEEE80211); 1415c38dbb97SDavid van Moolenbroek TEXT(AF_MPLS); 1416c38dbb97SDavid van Moolenbroek TEXT(AF_ROUTE); 1417c38dbb97SDavid van Moolenbroek } 1418c38dbb97SDavid van Moolenbroek } 1419c38dbb97SDavid van Moolenbroek 1420c38dbb97SDavid van Moolenbroek if (text != NULL) 1421c38dbb97SDavid van Moolenbroek put_field(proc, name, text); 1422c38dbb97SDavid van Moolenbroek else 1423c38dbb97SDavid van Moolenbroek put_value(proc, name, "%d", family); 1424c38dbb97SDavid van Moolenbroek } 1425c38dbb97SDavid van Moolenbroek 1426c38dbb97SDavid van Moolenbroek static const struct flags socket_types[] = { 1427c38dbb97SDavid van Moolenbroek FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_STREAM), 1428c38dbb97SDavid van Moolenbroek FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_DGRAM), 1429c38dbb97SDavid van Moolenbroek FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_RAW), 1430c38dbb97SDavid van Moolenbroek FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_RDM), 1431c38dbb97SDavid van Moolenbroek FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_SEQPACKET), 1432c38dbb97SDavid van Moolenbroek FLAG_MASK(~SOCK_FLAGS_MASK, SOCK_CONN_DGRAM), 1433c38dbb97SDavid van Moolenbroek FLAG(SOCK_CLOEXEC), 1434c38dbb97SDavid van Moolenbroek FLAG(SOCK_NONBLOCK), 1435c38dbb97SDavid van Moolenbroek FLAG(SOCK_NOSIGPIPE), 1436c38dbb97SDavid van Moolenbroek }; 1437c38dbb97SDavid van Moolenbroek 1438c38dbb97SDavid van Moolenbroek void 1439c38dbb97SDavid van Moolenbroek put_socket_type(struct trace_proc * proc, const char * name, int type) 1440c38dbb97SDavid van Moolenbroek { 1441c38dbb97SDavid van Moolenbroek 1442c38dbb97SDavid van Moolenbroek put_flags(proc, name, socket_types, COUNT(socket_types), "%d", type); 1443c38dbb97SDavid van Moolenbroek } 1444c38dbb97SDavid van Moolenbroek 1445c38dbb97SDavid van Moolenbroek static void 1446c38dbb97SDavid van Moolenbroek put_socket_protocol(struct trace_proc * proc, const char * name, int family, 1447c38dbb97SDavid van Moolenbroek int type, int protocol) 1448c38dbb97SDavid van Moolenbroek { 1449c38dbb97SDavid van Moolenbroek const char *text = NULL; 1450c38dbb97SDavid van Moolenbroek 1451c38dbb97SDavid van Moolenbroek if (!valuesonly && (type == SOCK_RAW || protocol != 0)) { 1452c38dbb97SDavid van Moolenbroek switch (family) { 1453c38dbb97SDavid van Moolenbroek case PF_INET: 1454c38dbb97SDavid van Moolenbroek case PF_INET6: 1455c38dbb97SDavid van Moolenbroek /* TODO: is this all that is used in socket(2)? */ 1456c38dbb97SDavid van Moolenbroek switch (protocol) { 1457c38dbb97SDavid van Moolenbroek TEXT(IPPROTO_IP); 1458c38dbb97SDavid van Moolenbroek TEXT(IPPROTO_ICMP); 1459c38dbb97SDavid van Moolenbroek TEXT(IPPROTO_IGMP); 1460c38dbb97SDavid van Moolenbroek TEXT(IPPROTO_TCP); 1461c38dbb97SDavid van Moolenbroek TEXT(IPPROTO_UDP); 1462c38dbb97SDavid van Moolenbroek TEXT(IPPROTO_ICMPV6); 1463c38dbb97SDavid van Moolenbroek TEXT(IPPROTO_RAW); 1464c38dbb97SDavid van Moolenbroek } 1465c38dbb97SDavid van Moolenbroek break; 1466c38dbb97SDavid van Moolenbroek #if 0 /* not yet */ 1467c38dbb97SDavid van Moolenbroek case PF_BLUETOOTH: 1468c38dbb97SDavid van Moolenbroek switch (protocol) { 1469c38dbb97SDavid van Moolenbroek TEXT(BTPROTO_HCI); 1470c38dbb97SDavid van Moolenbroek TEXT(BTPROTO_L2CAP); 1471c38dbb97SDavid van Moolenbroek TEXT(BTPROTO_RFCOMM); 1472c38dbb97SDavid van Moolenbroek TEXT(BTPROTO_SCO); 1473c38dbb97SDavid van Moolenbroek } 1474c38dbb97SDavid van Moolenbroek break; 1475c38dbb97SDavid van Moolenbroek #endif 1476c38dbb97SDavid van Moolenbroek } 1477c38dbb97SDavid van Moolenbroek } 1478c38dbb97SDavid van Moolenbroek 1479c38dbb97SDavid van Moolenbroek if (text != NULL) 1480c38dbb97SDavid van Moolenbroek put_field(proc, name, text); 1481c38dbb97SDavid van Moolenbroek else 1482c38dbb97SDavid van Moolenbroek put_value(proc, name, "%d", protocol); 1483c38dbb97SDavid van Moolenbroek } 1484c38dbb97SDavid van Moolenbroek 1485c38dbb97SDavid van Moolenbroek static int 1486c38dbb97SDavid van Moolenbroek vfs_socket_out(struct trace_proc * proc, const message * m_out) 1487c38dbb97SDavid van Moolenbroek { 1488c38dbb97SDavid van Moolenbroek 1489c38dbb97SDavid van Moolenbroek put_socket_family(proc, "domain", m_out->m_lc_vfs_socket.domain); 1490c38dbb97SDavid van Moolenbroek put_socket_type(proc, "type", m_out->m_lc_vfs_socket.type); 1491c38dbb97SDavid van Moolenbroek put_socket_protocol(proc, "protocol", m_out->m_lc_vfs_socket.domain, 1492c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_socket.type & ~SOCK_FLAGS_MASK, 1493c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_socket.protocol); 1494c38dbb97SDavid van Moolenbroek 1495c38dbb97SDavid van Moolenbroek return CT_DONE; 1496c38dbb97SDavid van Moolenbroek } 1497c38dbb97SDavid van Moolenbroek 1498c38dbb97SDavid van Moolenbroek static int 1499c38dbb97SDavid van Moolenbroek vfs_socketpair_out(struct trace_proc * proc, const message * m_out) 1500c38dbb97SDavid van Moolenbroek { 1501c38dbb97SDavid van Moolenbroek 1502c38dbb97SDavid van Moolenbroek put_socket_family(proc, "domain", m_out->m_lc_vfs_socket.domain); 1503c38dbb97SDavid van Moolenbroek put_socket_type(proc, "type", m_out->m_lc_vfs_socket.type); 1504c38dbb97SDavid van Moolenbroek put_socket_protocol(proc, "protocol", m_out->m_lc_vfs_socket.domain, 1505c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_socket.type & ~SOCK_FLAGS_MASK, 1506c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_socket.protocol); 1507c38dbb97SDavid van Moolenbroek 1508c38dbb97SDavid van Moolenbroek return CT_NOTDONE; 1509c38dbb97SDavid van Moolenbroek } 1510c38dbb97SDavid van Moolenbroek 1511c38dbb97SDavid van Moolenbroek static void 1512c38dbb97SDavid van Moolenbroek vfs_socketpair_in(struct trace_proc * proc, const message * m_out, 1513c38dbb97SDavid van Moolenbroek const message * m_in, int failed) 1514c38dbb97SDavid van Moolenbroek { 1515c38dbb97SDavid van Moolenbroek 1516c38dbb97SDavid van Moolenbroek if (!failed) { 1517c38dbb97SDavid van Moolenbroek put_open(proc, "fd", PF_NONAME, "[", ", "); 1518c38dbb97SDavid van Moolenbroek put_fd(proc, "fd0", m_in->m_vfs_lc_fdpair.fd0); 1519c38dbb97SDavid van Moolenbroek put_fd(proc, "fd1", m_in->m_vfs_lc_fdpair.fd1); 1520c38dbb97SDavid van Moolenbroek put_close(proc, "]"); 1521c38dbb97SDavid van Moolenbroek } else 1522c38dbb97SDavid van Moolenbroek put_field(proc, "fd", "&.."); 1523c38dbb97SDavid van Moolenbroek put_equals(proc); 1524c38dbb97SDavid van Moolenbroek put_result(proc); 1525c38dbb97SDavid van Moolenbroek } 1526c38dbb97SDavid van Moolenbroek 1527c38dbb97SDavid van Moolenbroek void 1528c38dbb97SDavid van Moolenbroek put_in_addr(struct trace_proc * proc, const char * name, struct in_addr in) 1529c38dbb97SDavid van Moolenbroek { 1530c38dbb97SDavid van Moolenbroek 1531c38dbb97SDavid van Moolenbroek if (!valuesonly) { 1532c38dbb97SDavid van Moolenbroek /* Is this an acceptable encapsulation? */ 1533c38dbb97SDavid van Moolenbroek put_value(proc, name, "[%s]", inet_ntoa(in)); 1534c38dbb97SDavid van Moolenbroek } else 1535c38dbb97SDavid van Moolenbroek put_value(proc, name, "0x%08x", ntohl(in.s_addr)); 1536c38dbb97SDavid van Moolenbroek } 1537c38dbb97SDavid van Moolenbroek 1538c38dbb97SDavid van Moolenbroek static void 1539c38dbb97SDavid van Moolenbroek put_in6_addr(struct trace_proc * proc, const char * name, struct in6_addr * in) 1540c38dbb97SDavid van Moolenbroek { 1541c38dbb97SDavid van Moolenbroek char buf[INET6_ADDRSTRLEN]; 1542c38dbb97SDavid van Moolenbroek const char *ptr; 1543c38dbb97SDavid van Moolenbroek unsigned int i, n; 1544c38dbb97SDavid van Moolenbroek 1545c38dbb97SDavid van Moolenbroek if (!valuesonly && 1546c38dbb97SDavid van Moolenbroek (ptr = inet_ntop(AF_INET6, in, buf, sizeof(buf))) != NULL) { 1547c38dbb97SDavid van Moolenbroek put_value(proc, name, "[%s]", ptr); 1548c38dbb97SDavid van Moolenbroek } else { 1549c38dbb97SDavid van Moolenbroek for (i = n = 0; i < 16; i++) 1550c38dbb97SDavid van Moolenbroek n += snprintf(buf + n, sizeof(buf) - n, "%02x", 1551c38dbb97SDavid van Moolenbroek ((unsigned char *)in)[i]); 1552c38dbb97SDavid van Moolenbroek put_value(proc, name, "0x%s", buf); 1553c38dbb97SDavid van Moolenbroek } 1554c38dbb97SDavid van Moolenbroek } 1555c38dbb97SDavid van Moolenbroek 1556c38dbb97SDavid van Moolenbroek static void 1557c38dbb97SDavid van Moolenbroek put_struct_sockaddr(struct trace_proc * proc, const char * name, int flags, 1558c38dbb97SDavid van Moolenbroek vir_bytes addr, socklen_t addr_len) 1559c38dbb97SDavid van Moolenbroek { 1560c38dbb97SDavid van Moolenbroek char buf[UCHAR_MAX + 1]; 1561c38dbb97SDavid van Moolenbroek uint8_t len; 1562c38dbb97SDavid van Moolenbroek sa_family_t family; 1563c38dbb97SDavid van Moolenbroek struct sockaddr sa; 1564c38dbb97SDavid van Moolenbroek struct sockaddr_in sin; 1565c38dbb97SDavid van Moolenbroek struct sockaddr_in6 sin6; 1566c38dbb97SDavid van Moolenbroek int all, off, left; 1567c38dbb97SDavid van Moolenbroek 1568c38dbb97SDavid van Moolenbroek /* 1569c38dbb97SDavid van Moolenbroek * For UNIX domain sockets, make sure there's always room to add a 1570c38dbb97SDavid van Moolenbroek * trailing NULL byte, because UDS paths are not necessarily null 1571c38dbb97SDavid van Moolenbroek * terminated. 1572c38dbb97SDavid van Moolenbroek */ 1573c38dbb97SDavid van Moolenbroek if (addr_len < offsetof(struct sockaddr, sa_data) || 1574c38dbb97SDavid van Moolenbroek addr_len >= sizeof(buf)) { 1575c38dbb97SDavid van Moolenbroek put_ptr(proc, name, addr); 1576c38dbb97SDavid van Moolenbroek 1577c38dbb97SDavid van Moolenbroek return; 1578c38dbb97SDavid van Moolenbroek } 1579c38dbb97SDavid van Moolenbroek 1580c38dbb97SDavid van Moolenbroek if (!put_open_struct(proc, name, flags, addr, buf, addr_len)) 1581c38dbb97SDavid van Moolenbroek return; 1582c38dbb97SDavid van Moolenbroek 1583c38dbb97SDavid van Moolenbroek memcpy(&sa, buf, sizeof(sa)); 1584c38dbb97SDavid van Moolenbroek len = sa.sa_len; 1585c38dbb97SDavid van Moolenbroek family = sa.sa_family; 1586c38dbb97SDavid van Moolenbroek all = (verbose > 1); 1587c38dbb97SDavid van Moolenbroek 1588c38dbb97SDavid van Moolenbroek switch (family) { 1589c38dbb97SDavid van Moolenbroek case AF_LOCAL: 1590c38dbb97SDavid van Moolenbroek if (verbose > 1) 1591c38dbb97SDavid van Moolenbroek put_value(proc, "sun_len", "%u", len); 1592c38dbb97SDavid van Moolenbroek if (verbose > 0) 1593c38dbb97SDavid van Moolenbroek put_socket_family(proc, "sun_family", family); 1594c38dbb97SDavid van Moolenbroek off = (int)offsetof(struct sockaddr_un, sun_path); 1595c38dbb97SDavid van Moolenbroek left = addr_len - off; 1596c38dbb97SDavid van Moolenbroek if (left > 0) { 1597c38dbb97SDavid van Moolenbroek buf[addr_len] = 0; /* force null termination */ 1598c38dbb97SDavid van Moolenbroek put_buf(proc, "sun_path", PF_LOCADDR | PF_PATH, 1599c38dbb97SDavid van Moolenbroek (vir_bytes)&buf[off], 1600c38dbb97SDavid van Moolenbroek left + 1 /* include null byte */); 1601c38dbb97SDavid van Moolenbroek } 1602c38dbb97SDavid van Moolenbroek break; 1603c38dbb97SDavid van Moolenbroek case AF_INET: 1604c38dbb97SDavid van Moolenbroek if (verbose > 1) 1605c38dbb97SDavid van Moolenbroek put_value(proc, "sin_len", "%u", len); 1606c38dbb97SDavid van Moolenbroek if (verbose > 0) 1607c38dbb97SDavid van Moolenbroek put_socket_family(proc, "sin_family", family); 1608c38dbb97SDavid van Moolenbroek if (addr_len == sizeof(sin)) { 1609c38dbb97SDavid van Moolenbroek memcpy(&sin, buf, sizeof(sin)); 1610c38dbb97SDavid van Moolenbroek put_value(proc, "sin_port", "%u", ntohs(sin.sin_port)); 1611c38dbb97SDavid van Moolenbroek put_in_addr(proc, "sin_addr", sin.sin_addr); 1612c38dbb97SDavid van Moolenbroek } else 1613c38dbb97SDavid van Moolenbroek all = FALSE; 1614c38dbb97SDavid van Moolenbroek break; 1615c38dbb97SDavid van Moolenbroek case AF_INET6: 1616c38dbb97SDavid van Moolenbroek if (verbose > 1) 1617c38dbb97SDavid van Moolenbroek put_value(proc, "sin6_len", "%u", len); 1618c38dbb97SDavid van Moolenbroek if (verbose > 0) 1619c38dbb97SDavid van Moolenbroek put_socket_family(proc, "sin6_family", family); 1620c38dbb97SDavid van Moolenbroek if (addr_len == sizeof(sin6)) { 1621c38dbb97SDavid van Moolenbroek memcpy(&sin6, buf, sizeof(sin6)); 1622c38dbb97SDavid van Moolenbroek put_value(proc, "sin6_port", "%u", 1623c38dbb97SDavid van Moolenbroek ntohs(sin6.sin6_port)); 1624c38dbb97SDavid van Moolenbroek if (verbose > 1) 1625c38dbb97SDavid van Moolenbroek put_value(proc, "sin6_flowinfo", "%"PRIu32, 1626c38dbb97SDavid van Moolenbroek sin6.sin6_flowinfo); 1627c38dbb97SDavid van Moolenbroek put_in6_addr(proc, "sin6_addr", &sin6.sin6_addr); 1628c38dbb97SDavid van Moolenbroek if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) || 1629*40dec70cSDavid van Moolenbroek IN6_IS_ADDR_MC_NODELOCAL(&sin6.sin6_addr) || 1630*40dec70cSDavid van Moolenbroek IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr) || 1631c38dbb97SDavid van Moolenbroek verbose > 0) 1632c38dbb97SDavid van Moolenbroek put_value(proc, "sin6_scope_id", "%"PRIu32, 1633c38dbb97SDavid van Moolenbroek sin6.sin6_scope_id); 1634c38dbb97SDavid van Moolenbroek } else 1635c38dbb97SDavid van Moolenbroek all = FALSE; 1636c38dbb97SDavid van Moolenbroek break; 1637c38dbb97SDavid van Moolenbroek /* TODO: support for other address families */ 1638c38dbb97SDavid van Moolenbroek default: 1639c38dbb97SDavid van Moolenbroek if (verbose > 1) 1640c38dbb97SDavid van Moolenbroek put_value(proc, "sa_len", "%u", len); 1641c38dbb97SDavid van Moolenbroek put_socket_family(proc, "sa_family", family); 1642c38dbb97SDavid van Moolenbroek all = (verbose > 1 && family == AF_UNSPEC); 1643c38dbb97SDavid van Moolenbroek } 1644c38dbb97SDavid van Moolenbroek 1645c38dbb97SDavid van Moolenbroek put_close_struct(proc, all); 1646c38dbb97SDavid van Moolenbroek } 1647c38dbb97SDavid van Moolenbroek 1648c38dbb97SDavid van Moolenbroek /* This function is shared between bind and connect. */ 1649c38dbb97SDavid van Moolenbroek static int 1650c38dbb97SDavid van Moolenbroek vfs_bind_out(struct trace_proc * proc, const message * m_out) 1651c38dbb97SDavid van Moolenbroek { 1652c38dbb97SDavid van Moolenbroek 1653c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sockaddr.fd); 1654c38dbb97SDavid van Moolenbroek put_struct_sockaddr(proc, "addr", 0, m_out->m_lc_vfs_sockaddr.addr, 1655c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sockaddr.addr_len); 1656c38dbb97SDavid van Moolenbroek put_value(proc, "addr_len", "%u", m_out->m_lc_vfs_sockaddr.addr_len); 1657c38dbb97SDavid van Moolenbroek 1658c38dbb97SDavid van Moolenbroek return CT_DONE; 1659c38dbb97SDavid van Moolenbroek } 1660c38dbb97SDavid van Moolenbroek 1661c38dbb97SDavid van Moolenbroek static int 1662c38dbb97SDavid van Moolenbroek vfs_listen_out(struct trace_proc * proc, const message * m_out) 1663c38dbb97SDavid van Moolenbroek { 1664c38dbb97SDavid van Moolenbroek 1665c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_listen.fd); 1666c38dbb97SDavid van Moolenbroek put_value(proc, "backlog", "%d", m_out->m_lc_vfs_listen.backlog); 1667c38dbb97SDavid van Moolenbroek 1668c38dbb97SDavid van Moolenbroek return CT_DONE; 1669c38dbb97SDavid van Moolenbroek } 1670c38dbb97SDavid van Moolenbroek 1671c38dbb97SDavid van Moolenbroek static int 1672c38dbb97SDavid van Moolenbroek vfs_accept_out(struct trace_proc * proc, const message * m_out) 1673c38dbb97SDavid van Moolenbroek { 1674c38dbb97SDavid van Moolenbroek 1675c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sockaddr.fd); 1676c38dbb97SDavid van Moolenbroek 1677c38dbb97SDavid van Moolenbroek return CT_NOTDONE; 1678c38dbb97SDavid van Moolenbroek } 1679c38dbb97SDavid van Moolenbroek 1680c38dbb97SDavid van Moolenbroek static void 1681c38dbb97SDavid van Moolenbroek vfs_accept_in(struct trace_proc * proc, const message * m_out, 1682c38dbb97SDavid van Moolenbroek const message * m_in, int failed) 1683c38dbb97SDavid van Moolenbroek { 1684c38dbb97SDavid van Moolenbroek 1685c38dbb97SDavid van Moolenbroek put_struct_sockaddr(proc, "addr", failed, 1686c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sockaddr.addr, m_in->m_vfs_lc_socklen.len); 1687c38dbb97SDavid van Moolenbroek /* 1688c38dbb97SDavid van Moolenbroek * We print the resulting address length rather than the given buffer 1689c38dbb97SDavid van Moolenbroek * size here, as we do in recvfrom, getsockname, getpeername, and (less 1690c38dbb97SDavid van Moolenbroek * explicitly) recvmsg. We could also print both, by adding the 1691c38dbb97SDavid van Moolenbroek * resulting length after the call result. 1692c38dbb97SDavid van Moolenbroek */ 1693c38dbb97SDavid van Moolenbroek if (m_out->m_lc_vfs_sockaddr.addr == 0) 1694c38dbb97SDavid van Moolenbroek put_field(proc, "addr_len", "NULL"); 1695c38dbb97SDavid van Moolenbroek else if (!failed) 1696c38dbb97SDavid van Moolenbroek put_value(proc, "addr_len", "{%u}", 1697c38dbb97SDavid van Moolenbroek m_in->m_vfs_lc_socklen.len); 1698c38dbb97SDavid van Moolenbroek else 1699c38dbb97SDavid van Moolenbroek put_field(proc, "addr_len", "&.."); 1700c38dbb97SDavid van Moolenbroek 1701c38dbb97SDavid van Moolenbroek put_equals(proc); 1702c38dbb97SDavid van Moolenbroek put_result(proc); 1703c38dbb97SDavid van Moolenbroek } 1704c38dbb97SDavid van Moolenbroek 1705c38dbb97SDavid van Moolenbroek static const struct flags msg_flags[] = { 1706c38dbb97SDavid van Moolenbroek FLAG(MSG_OOB), 1707c38dbb97SDavid van Moolenbroek FLAG(MSG_PEEK), 1708c38dbb97SDavid van Moolenbroek FLAG(MSG_DONTROUTE), 1709c38dbb97SDavid van Moolenbroek FLAG(MSG_EOR), 1710c38dbb97SDavid van Moolenbroek FLAG(MSG_TRUNC), 1711c38dbb97SDavid van Moolenbroek FLAG(MSG_CTRUNC), 1712c38dbb97SDavid van Moolenbroek FLAG(MSG_WAITALL), 1713c38dbb97SDavid van Moolenbroek FLAG(MSG_DONTWAIT), 1714c38dbb97SDavid van Moolenbroek FLAG(MSG_BCAST), 1715c38dbb97SDavid van Moolenbroek FLAG(MSG_MCAST), 1716c38dbb97SDavid van Moolenbroek #ifdef MSG_NOSIGNAL 1717c38dbb97SDavid van Moolenbroek FLAG(MSG_NOSIGNAL), 1718c38dbb97SDavid van Moolenbroek #endif 1719c38dbb97SDavid van Moolenbroek FLAG(MSG_CMSG_CLOEXEC), 1720c38dbb97SDavid van Moolenbroek FLAG(MSG_NBIO), 1721c38dbb97SDavid van Moolenbroek FLAG(MSG_WAITFORONE), 1722c38dbb97SDavid van Moolenbroek }; 1723c38dbb97SDavid van Moolenbroek 1724c38dbb97SDavid van Moolenbroek static int 1725c38dbb97SDavid van Moolenbroek vfs_sendto_out(struct trace_proc * proc, const message * m_out) 1726c38dbb97SDavid van Moolenbroek { 1727c38dbb97SDavid van Moolenbroek 1728c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sendrecv.fd); 1729c38dbb97SDavid van Moolenbroek put_buf(proc, "buf", 0, m_out->m_lc_vfs_sendrecv.buf, 1730c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_readwrite.len); 1731c38dbb97SDavid van Moolenbroek put_value(proc, "len", "%zu", m_out->m_lc_vfs_sendrecv.len); 1732c38dbb97SDavid van Moolenbroek put_flags(proc, "flags", msg_flags, COUNT(msg_flags), "0x%x", 1733c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sendrecv.flags); 1734c38dbb97SDavid van Moolenbroek put_struct_sockaddr(proc, "addr", 0, m_out->m_lc_vfs_sendrecv.addr, 1735c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sendrecv.addr_len); 1736c38dbb97SDavid van Moolenbroek put_value(proc, "addr_len", "%u", m_out->m_lc_vfs_sendrecv.addr_len); 1737c38dbb97SDavid van Moolenbroek 1738c38dbb97SDavid van Moolenbroek return CT_DONE; 1739c38dbb97SDavid van Moolenbroek } 1740c38dbb97SDavid van Moolenbroek 1741c38dbb97SDavid van Moolenbroek static void 1742c38dbb97SDavid van Moolenbroek put_struct_iovec(struct trace_proc * proc, const char * name, int flags, 1743c38dbb97SDavid van Moolenbroek vir_bytes addr, int len, ssize_t bmax) 1744c38dbb97SDavid van Moolenbroek { 1745c38dbb97SDavid van Moolenbroek struct iovec iov; 1746c38dbb97SDavid van Moolenbroek size_t bytes; 1747c38dbb97SDavid van Moolenbroek int i, imax; 1748c38dbb97SDavid van Moolenbroek 1749c38dbb97SDavid van Moolenbroek /* 1750c38dbb97SDavid van Moolenbroek * For simplicity and clarity reasons, we currently print the I/O 1751c38dbb97SDavid van Moolenbroek * vector as an array of data elements rather than an array of 1752c38dbb97SDavid van Moolenbroek * structures. We also copy in each element separately, because as of 1753c38dbb97SDavid van Moolenbroek * writing there is no system support for more than one element anyway. 1754c38dbb97SDavid van Moolenbroek * All of this may be changed later. 1755c38dbb97SDavid van Moolenbroek */ 1756c38dbb97SDavid van Moolenbroek if ((flags & PF_FAILED) || valuesonly > 1 || addr == 0 || len < 0) { 1757c38dbb97SDavid van Moolenbroek put_ptr(proc, name, addr); 1758c38dbb97SDavid van Moolenbroek 1759c38dbb97SDavid van Moolenbroek return; 1760c38dbb97SDavid van Moolenbroek } 1761c38dbb97SDavid van Moolenbroek 1762c38dbb97SDavid van Moolenbroek if (len == 0 || bmax == 0) { 1763c38dbb97SDavid van Moolenbroek put_field(proc, name, "[]"); 1764c38dbb97SDavid van Moolenbroek 1765c38dbb97SDavid van Moolenbroek return; 1766c38dbb97SDavid van Moolenbroek } 1767c38dbb97SDavid van Moolenbroek 1768c38dbb97SDavid van Moolenbroek /* As per logic below, 'imax' must be set to a nonzero value here. */ 1769c38dbb97SDavid van Moolenbroek if (verbose == 0) 1770c38dbb97SDavid van Moolenbroek imax = 4; 1771c38dbb97SDavid van Moolenbroek else if (verbose == 1) 1772c38dbb97SDavid van Moolenbroek imax = 16; 1773c38dbb97SDavid van Moolenbroek else 1774c38dbb97SDavid van Moolenbroek imax = INT_MAX; 1775c38dbb97SDavid van Moolenbroek 1776c38dbb97SDavid van Moolenbroek for (i = 0; i < len && bmax > 0; i++) { 1777c38dbb97SDavid van Moolenbroek if (mem_get_data(proc->pid, addr, &iov, sizeof(iov)) < 0) { 1778c38dbb97SDavid van Moolenbroek if (i == 0) { 1779c38dbb97SDavid van Moolenbroek put_ptr(proc, name, addr); 1780c38dbb97SDavid van Moolenbroek 1781c38dbb97SDavid van Moolenbroek return; 1782c38dbb97SDavid van Moolenbroek } 1783c38dbb97SDavid van Moolenbroek 1784c38dbb97SDavid van Moolenbroek len = imax = 0; /* make put_tail() print an error */ 1785c38dbb97SDavid van Moolenbroek break; 1786c38dbb97SDavid van Moolenbroek } 1787c38dbb97SDavid van Moolenbroek 1788c38dbb97SDavid van Moolenbroek if (i == 0) 1789c38dbb97SDavid van Moolenbroek put_open(proc, name, 0, "[", ", "); 1790c38dbb97SDavid van Moolenbroek 1791c38dbb97SDavid van Moolenbroek bytes = MIN(iov.iov_len, (size_t)bmax); 1792c38dbb97SDavid van Moolenbroek 1793c38dbb97SDavid van Moolenbroek if (len < imax) 1794c38dbb97SDavid van Moolenbroek put_buf(proc, NULL, 0, (vir_bytes)iov.iov_base, bytes); 1795c38dbb97SDavid van Moolenbroek 1796c38dbb97SDavid van Moolenbroek addr += sizeof(struct iovec); 1797c38dbb97SDavid van Moolenbroek bmax -= bytes; 1798c38dbb97SDavid van Moolenbroek } 1799c38dbb97SDavid van Moolenbroek 1800c38dbb97SDavid van Moolenbroek if (imax == 0 || imax < len) 1801c38dbb97SDavid van Moolenbroek put_tail(proc, len, imax); 1802c38dbb97SDavid van Moolenbroek put_close(proc, "]"); 1803c38dbb97SDavid van Moolenbroek } 1804c38dbb97SDavid van Moolenbroek 1805c38dbb97SDavid van Moolenbroek void 1806c38dbb97SDavid van Moolenbroek put_struct_uucred(struct trace_proc * proc, const char * name, int flags, 1807c38dbb97SDavid van Moolenbroek vir_bytes addr) 1808c38dbb97SDavid van Moolenbroek { 1809c38dbb97SDavid van Moolenbroek struct uucred cred; 1810c38dbb97SDavid van Moolenbroek 1811c38dbb97SDavid van Moolenbroek if (!put_open_struct(proc, name, flags, addr, &cred, sizeof(cred))) 1812c38dbb97SDavid van Moolenbroek return; 1813c38dbb97SDavid van Moolenbroek 1814c38dbb97SDavid van Moolenbroek put_value(proc, "cr_uid", "%u", cred.cr_uid); 1815c38dbb97SDavid van Moolenbroek if (verbose > 0) { 1816c38dbb97SDavid van Moolenbroek put_value(proc, "cr_gid", "%u", cred.cr_gid); 1817c38dbb97SDavid van Moolenbroek if (verbose > 1) 1818c38dbb97SDavid van Moolenbroek put_value(proc, "cr_ngroups", "%d", cred.cr_ngroups); 1819c38dbb97SDavid van Moolenbroek put_groups(proc, "cr_groups", PF_LOCADDR, 1820c38dbb97SDavid van Moolenbroek (vir_bytes)&cred.cr_groups, cred.cr_ngroups); 1821c38dbb97SDavid van Moolenbroek } 1822c38dbb97SDavid van Moolenbroek 1823c38dbb97SDavid van Moolenbroek put_close_struct(proc, verbose > 0); 1824c38dbb97SDavid van Moolenbroek } 1825c38dbb97SDavid van Moolenbroek 1826c38dbb97SDavid van Moolenbroek static void 1827c38dbb97SDavid van Moolenbroek put_socket_level(struct trace_proc * proc, const char * name, int level) 1828c38dbb97SDavid van Moolenbroek { 1829c38dbb97SDavid van Moolenbroek 1830c38dbb97SDavid van Moolenbroek /* 1831c38dbb97SDavid van Moolenbroek * Unfortunately, the level is a domain-specific protocol number. That 1832c38dbb97SDavid van Moolenbroek * means that without knowing how the socket was created, we cannot 1833c38dbb97SDavid van Moolenbroek * tell what it means. The only thing we can print is SOL_SOCKET, 1834c38dbb97SDavid van Moolenbroek * which is the same across all domains. 1835c38dbb97SDavid van Moolenbroek */ 1836c38dbb97SDavid van Moolenbroek if (!valuesonly && level == SOL_SOCKET) 1837c38dbb97SDavid van Moolenbroek put_field(proc, name, "SOL_SOCKET"); 1838c38dbb97SDavid van Moolenbroek else 1839c38dbb97SDavid van Moolenbroek put_value(proc, name, "%d", level); 1840c38dbb97SDavid van Moolenbroek } 1841c38dbb97SDavid van Moolenbroek 1842c38dbb97SDavid van Moolenbroek void 1843c38dbb97SDavid van Moolenbroek put_cmsg_type(struct trace_proc * proc, const char * name, int type) 1844c38dbb97SDavid van Moolenbroek { 1845c38dbb97SDavid van Moolenbroek const char *text = NULL; 1846c38dbb97SDavid van Moolenbroek 1847c38dbb97SDavid van Moolenbroek if (!valuesonly) { 1848c38dbb97SDavid van Moolenbroek switch (type) { 1849c38dbb97SDavid van Moolenbroek TEXT(SCM_RIGHTS); 1850c38dbb97SDavid van Moolenbroek TEXT(SCM_CREDS); 1851c38dbb97SDavid van Moolenbroek TEXT(SCM_TIMESTAMP); 1852c38dbb97SDavid van Moolenbroek } 1853c38dbb97SDavid van Moolenbroek } 1854c38dbb97SDavid van Moolenbroek 1855c38dbb97SDavid van Moolenbroek if (text != NULL) 1856c38dbb97SDavid van Moolenbroek put_field(proc, name, text); 1857c38dbb97SDavid van Moolenbroek else 1858c38dbb97SDavid van Moolenbroek put_value(proc, name, "%d", type); 1859c38dbb97SDavid van Moolenbroek } 1860c38dbb97SDavid van Moolenbroek 1861c38dbb97SDavid van Moolenbroek static void 1862c38dbb97SDavid van Moolenbroek put_cmsg_rights(struct trace_proc * proc, const char * name, char * buf, 1863c38dbb97SDavid van Moolenbroek size_t size, char * cptr, size_t chunk, vir_bytes addr, size_t len) 1864c38dbb97SDavid van Moolenbroek { 1865c38dbb97SDavid van Moolenbroek unsigned int i, nfds; 1866c38dbb97SDavid van Moolenbroek int *ptr; 1867c38dbb97SDavid van Moolenbroek 1868c38dbb97SDavid van Moolenbroek put_open(proc, name, PF_NONAME, "[", ", "); 1869c38dbb97SDavid van Moolenbroek 1870c38dbb97SDavid van Moolenbroek /* 1871c38dbb97SDavid van Moolenbroek * Since file descriptors are important, we print them all, regardless 1872c38dbb97SDavid van Moolenbroek * of the current verbosity level. Start with the file descriptors 1873c38dbb97SDavid van Moolenbroek * that are already copied into the local buffer. 1874c38dbb97SDavid van Moolenbroek */ 1875c38dbb97SDavid van Moolenbroek ptr = (int *)cptr; 1876c38dbb97SDavid van Moolenbroek chunk = MIN(chunk, len); 1877c38dbb97SDavid van Moolenbroek 1878c38dbb97SDavid van Moolenbroek nfds = chunk / sizeof(int); 1879c38dbb97SDavid van Moolenbroek for (i = 0; i < nfds; i++) 1880c38dbb97SDavid van Moolenbroek put_fd(proc, NULL, ptr[i]); 1881c38dbb97SDavid van Moolenbroek 1882c38dbb97SDavid van Moolenbroek /* Then do the remaining file descriptors, in chunks. */ 1883c38dbb97SDavid van Moolenbroek size -= size % sizeof(int); 1884c38dbb97SDavid van Moolenbroek 1885c38dbb97SDavid van Moolenbroek for (len -= chunk; len >= sizeof(int); len -= chunk) { 1886c38dbb97SDavid van Moolenbroek chunk = MIN(len, size); 1887c38dbb97SDavid van Moolenbroek 1888c38dbb97SDavid van Moolenbroek if (mem_get_data(proc->pid, addr, buf, chunk) < 0) { 1889c38dbb97SDavid van Moolenbroek put_field(proc, NULL, ".."); 1890c38dbb97SDavid van Moolenbroek 1891c38dbb97SDavid van Moolenbroek break; 1892c38dbb97SDavid van Moolenbroek } 1893c38dbb97SDavid van Moolenbroek 1894c38dbb97SDavid van Moolenbroek ptr = (int *)buf; 1895c38dbb97SDavid van Moolenbroek nfds = chunk / sizeof(int); 1896c38dbb97SDavid van Moolenbroek for (i = 0; i < nfds; i++) 1897c38dbb97SDavid van Moolenbroek put_fd(proc, NULL, ptr[i]); 1898c38dbb97SDavid van Moolenbroek 1899c38dbb97SDavid van Moolenbroek addr += chunk; 1900c38dbb97SDavid van Moolenbroek } 1901c38dbb97SDavid van Moolenbroek 1902c38dbb97SDavid van Moolenbroek put_close(proc, "]"); 1903c38dbb97SDavid van Moolenbroek } 1904c38dbb97SDavid van Moolenbroek 1905c38dbb97SDavid van Moolenbroek static void 1906c38dbb97SDavid van Moolenbroek put_cmsg(struct trace_proc * proc, const char * name, vir_bytes addr, 1907c38dbb97SDavid van Moolenbroek size_t len) 1908c38dbb97SDavid van Moolenbroek { 1909c38dbb97SDavid van Moolenbroek struct cmsghdr cmsg; 1910c38dbb97SDavid van Moolenbroek char buf[CMSG_SPACE(sizeof(struct uucred))]; 1911c38dbb97SDavid van Moolenbroek size_t off, chunk, datalen; 1912c38dbb97SDavid van Moolenbroek 1913c38dbb97SDavid van Moolenbroek if (valuesonly > 1 || addr == 0 || len < CMSG_LEN(0)) { 1914c38dbb97SDavid van Moolenbroek put_ptr(proc, name, addr); 1915c38dbb97SDavid van Moolenbroek 1916c38dbb97SDavid van Moolenbroek return; 1917c38dbb97SDavid van Moolenbroek } 1918c38dbb97SDavid van Moolenbroek 1919c38dbb97SDavid van Moolenbroek for (off = 0; off < len; off += CMSG_SPACE(datalen)) { 1920c38dbb97SDavid van Moolenbroek chunk = MIN(len - off, sizeof(buf)); 1921c38dbb97SDavid van Moolenbroek 1922c38dbb97SDavid van Moolenbroek if (chunk < CMSG_LEN(0)) 1923c38dbb97SDavid van Moolenbroek break; 1924c38dbb97SDavid van Moolenbroek 1925c38dbb97SDavid van Moolenbroek if (mem_get_data(proc->pid, addr + off, buf, chunk) < 0) { 1926c38dbb97SDavid van Moolenbroek if (off == 0) { 1927c38dbb97SDavid van Moolenbroek put_ptr(proc, name, addr); 1928c38dbb97SDavid van Moolenbroek 1929c38dbb97SDavid van Moolenbroek return; 1930c38dbb97SDavid van Moolenbroek } 1931c38dbb97SDavid van Moolenbroek break; 1932c38dbb97SDavid van Moolenbroek } 1933c38dbb97SDavid van Moolenbroek 1934c38dbb97SDavid van Moolenbroek if (off == 0) 1935c38dbb97SDavid van Moolenbroek put_open(proc, name, 0, "[", ", "); 1936c38dbb97SDavid van Moolenbroek 1937c38dbb97SDavid van Moolenbroek memcpy(&cmsg, buf, sizeof(cmsg)); 1938c38dbb97SDavid van Moolenbroek 1939c38dbb97SDavid van Moolenbroek put_open(proc, NULL, 0, "{", ", "); 1940c38dbb97SDavid van Moolenbroek if (verbose > 0) 1941c38dbb97SDavid van Moolenbroek put_value(proc, "cmsg_len", "%u", cmsg.cmsg_len); 1942c38dbb97SDavid van Moolenbroek put_socket_level(proc, "cmsg_level", cmsg.cmsg_level); 1943c38dbb97SDavid van Moolenbroek if (cmsg.cmsg_level == SOL_SOCKET) 1944c38dbb97SDavid van Moolenbroek put_cmsg_type(proc, "cmsg_type", cmsg.cmsg_type); 1945c38dbb97SDavid van Moolenbroek else 1946c38dbb97SDavid van Moolenbroek put_value(proc, "cmsg_type", "%d", cmsg.cmsg_type); 1947c38dbb97SDavid van Moolenbroek 1948c38dbb97SDavid van Moolenbroek if (cmsg.cmsg_len < CMSG_LEN(0) || off + cmsg.cmsg_len > len) { 1949c38dbb97SDavid van Moolenbroek put_tail(proc, 0, 0); 1950c38dbb97SDavid van Moolenbroek put_close(proc, "}"); 1951c38dbb97SDavid van Moolenbroek break; 1952c38dbb97SDavid van Moolenbroek } 1953c38dbb97SDavid van Moolenbroek 1954c38dbb97SDavid van Moolenbroek datalen = cmsg.cmsg_len - CMSG_LEN(0); 1955c38dbb97SDavid van Moolenbroek 1956c38dbb97SDavid van Moolenbroek if (cmsg.cmsg_level == SOL_SOCKET && 1957c38dbb97SDavid van Moolenbroek cmsg.cmsg_type == SCM_RIGHTS) { 1958c38dbb97SDavid van Moolenbroek put_cmsg_rights(proc, "cmsg_data", buf, sizeof(buf), 1959c38dbb97SDavid van Moolenbroek &buf[CMSG_LEN(0)], chunk - CMSG_LEN(0), 1960c38dbb97SDavid van Moolenbroek addr + off + chunk, datalen); 1961c38dbb97SDavid van Moolenbroek } else if (cmsg.cmsg_level == SOL_SOCKET && 1962c38dbb97SDavid van Moolenbroek cmsg.cmsg_type == SCM_CREDS && 1963c38dbb97SDavid van Moolenbroek datalen >= sizeof(struct uucred) && 1964c38dbb97SDavid van Moolenbroek chunk >= CMSG_LEN(datalen)) { 1965c38dbb97SDavid van Moolenbroek put_struct_uucred(proc, "cmsg_data", PF_LOCADDR, 1966c38dbb97SDavid van Moolenbroek (vir_bytes)&buf[CMSG_LEN(0)]); 1967c38dbb97SDavid van Moolenbroek } else if (datalen > 0) 1968c38dbb97SDavid van Moolenbroek put_field(proc, "cmsg_data", ".."); 1969c38dbb97SDavid van Moolenbroek 1970c38dbb97SDavid van Moolenbroek if (verbose == 0) 1971c38dbb97SDavid van Moolenbroek put_field(proc, NULL, ".."); 1972c38dbb97SDavid van Moolenbroek put_close(proc, "}"); 1973c38dbb97SDavid van Moolenbroek } 1974c38dbb97SDavid van Moolenbroek 1975c38dbb97SDavid van Moolenbroek if (off < len) 1976c38dbb97SDavid van Moolenbroek put_field(proc, NULL, ".."); 1977c38dbb97SDavid van Moolenbroek put_close(proc, "]"); 1978c38dbb97SDavid van Moolenbroek } 1979c38dbb97SDavid van Moolenbroek 1980c38dbb97SDavid van Moolenbroek static void 1981c38dbb97SDavid van Moolenbroek put_struct_msghdr(struct trace_proc * proc, const char * name, int flags, 1982c38dbb97SDavid van Moolenbroek vir_bytes addr, ssize_t max) 1983c38dbb97SDavid van Moolenbroek { 1984c38dbb97SDavid van Moolenbroek struct msghdr msg; 1985c38dbb97SDavid van Moolenbroek int all; 1986c38dbb97SDavid van Moolenbroek 1987c38dbb97SDavid van Moolenbroek if (!put_open_struct(proc, name, flags, addr, &msg, sizeof(msg))) 1988c38dbb97SDavid van Moolenbroek return; 1989c38dbb97SDavid van Moolenbroek 1990c38dbb97SDavid van Moolenbroek all = TRUE; 1991c38dbb97SDavid van Moolenbroek 1992c38dbb97SDavid van Moolenbroek if (msg.msg_name != NULL || verbose > 1) { 1993c38dbb97SDavid van Moolenbroek put_struct_sockaddr(proc, "msg_name", 0, 1994c38dbb97SDavid van Moolenbroek (vir_bytes)msg.msg_name, msg.msg_namelen); 1995c38dbb97SDavid van Moolenbroek if (verbose > 0) 1996c38dbb97SDavid van Moolenbroek put_value(proc, "msg_namelen", "%u", msg.msg_namelen); 1997c38dbb97SDavid van Moolenbroek else 1998c38dbb97SDavid van Moolenbroek all = FALSE; 1999c38dbb97SDavid van Moolenbroek } else 2000c38dbb97SDavid van Moolenbroek all = FALSE; 2001c38dbb97SDavid van Moolenbroek 2002c38dbb97SDavid van Moolenbroek put_struct_iovec(proc, "msg_iov", 0, (vir_bytes)msg.msg_iov, 2003c38dbb97SDavid van Moolenbroek msg.msg_iovlen, max); 2004c38dbb97SDavid van Moolenbroek if (verbose > 0) 2005c38dbb97SDavid van Moolenbroek put_value(proc, "msg_iovlen", "%d", msg.msg_iovlen); 2006c38dbb97SDavid van Moolenbroek else 2007c38dbb97SDavid van Moolenbroek all = FALSE; 2008c38dbb97SDavid van Moolenbroek 2009c38dbb97SDavid van Moolenbroek if (msg.msg_control != NULL || verbose > 1) { 2010c38dbb97SDavid van Moolenbroek put_cmsg(proc, "msg_control", (vir_bytes)msg.msg_control, 2011c38dbb97SDavid van Moolenbroek msg.msg_controllen); 2012c38dbb97SDavid van Moolenbroek 2013c38dbb97SDavid van Moolenbroek if (verbose > 0) 2014c38dbb97SDavid van Moolenbroek put_value(proc, "msg_controllen", "%u", 2015c38dbb97SDavid van Moolenbroek msg.msg_controllen); 2016c38dbb97SDavid van Moolenbroek else 2017c38dbb97SDavid van Moolenbroek all = FALSE; 2018c38dbb97SDavid van Moolenbroek } else 2019c38dbb97SDavid van Moolenbroek all = FALSE; 2020c38dbb97SDavid van Moolenbroek 2021c38dbb97SDavid van Moolenbroek /* When receiving, print the flags field as well. */ 2022c38dbb97SDavid van Moolenbroek if (flags & PF_ALT) 2023c38dbb97SDavid van Moolenbroek put_flags(proc, "msg_flags", msg_flags, COUNT(msg_flags), 2024c38dbb97SDavid van Moolenbroek "0x%x", msg.msg_flags); 2025c38dbb97SDavid van Moolenbroek 2026c38dbb97SDavid van Moolenbroek put_close_struct(proc, all); 2027c38dbb97SDavid van Moolenbroek } 2028c38dbb97SDavid van Moolenbroek 2029c38dbb97SDavid van Moolenbroek static int 2030c38dbb97SDavid van Moolenbroek vfs_sendmsg_out(struct trace_proc * proc, const message * m_out) 2031c38dbb97SDavid van Moolenbroek { 2032c38dbb97SDavid van Moolenbroek 2033c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sockmsg.fd); 2034c38dbb97SDavid van Moolenbroek put_struct_msghdr(proc, "msg", 0, m_out->m_lc_vfs_sockmsg.msgbuf, 2035c38dbb97SDavid van Moolenbroek SSIZE_MAX); 2036c38dbb97SDavid van Moolenbroek put_flags(proc, "flags", msg_flags, COUNT(msg_flags), "0x%x", 2037c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sockmsg.flags); 2038c38dbb97SDavid van Moolenbroek 2039c38dbb97SDavid van Moolenbroek return CT_DONE; 2040c38dbb97SDavid van Moolenbroek } 2041c38dbb97SDavid van Moolenbroek 2042c38dbb97SDavid van Moolenbroek static int 2043c38dbb97SDavid van Moolenbroek vfs_recvfrom_out(struct trace_proc * proc, const message * m_out) 2044c38dbb97SDavid van Moolenbroek { 2045c38dbb97SDavid van Moolenbroek 2046c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sendrecv.fd); 2047c38dbb97SDavid van Moolenbroek 2048c38dbb97SDavid van Moolenbroek return CT_NOTDONE; 2049c38dbb97SDavid van Moolenbroek } 2050c38dbb97SDavid van Moolenbroek 2051c38dbb97SDavid van Moolenbroek static void 2052c38dbb97SDavid van Moolenbroek vfs_recvfrom_in(struct trace_proc * proc, const message * m_out, 2053c38dbb97SDavid van Moolenbroek const message * m_in, int failed) 2054c38dbb97SDavid van Moolenbroek { 2055c38dbb97SDavid van Moolenbroek 2056c38dbb97SDavid van Moolenbroek put_buf(proc, "buf", failed, m_out->m_lc_vfs_sendrecv.buf, 2057c38dbb97SDavid van Moolenbroek m_in->m_type); 2058c38dbb97SDavid van Moolenbroek put_value(proc, "len", "%zu", m_out->m_lc_vfs_sendrecv.len); 2059c38dbb97SDavid van Moolenbroek put_flags(proc, "flags", msg_flags, COUNT(msg_flags), "0x%x", 2060c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sendrecv.flags); 2061c38dbb97SDavid van Moolenbroek put_struct_sockaddr(proc, "addr", failed, 2062c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sendrecv.addr, m_in->m_vfs_lc_socklen.len); 2063c38dbb97SDavid van Moolenbroek if (m_out->m_lc_vfs_sendrecv.addr == 0) 2064c38dbb97SDavid van Moolenbroek put_field(proc, "addr_len", "NULL"); 2065c38dbb97SDavid van Moolenbroek else if (!failed) 2066c38dbb97SDavid van Moolenbroek put_value(proc, "addr_len", "{%u}", 2067c38dbb97SDavid van Moolenbroek m_in->m_vfs_lc_socklen.len); 2068c38dbb97SDavid van Moolenbroek else 2069c38dbb97SDavid van Moolenbroek put_field(proc, "addr_len", "&.."); 2070c38dbb97SDavid van Moolenbroek 2071c38dbb97SDavid van Moolenbroek put_equals(proc); 2072c38dbb97SDavid van Moolenbroek put_result(proc); 2073c38dbb97SDavid van Moolenbroek } 2074c38dbb97SDavid van Moolenbroek 2075c38dbb97SDavid van Moolenbroek static int 2076c38dbb97SDavid van Moolenbroek vfs_recvmsg_out(struct trace_proc * proc, const message * m_out) 2077c38dbb97SDavid van Moolenbroek { 2078c38dbb97SDavid van Moolenbroek 2079c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sockmsg.fd); 2080c38dbb97SDavid van Moolenbroek 2081c38dbb97SDavid van Moolenbroek return CT_NOTDONE; 2082c38dbb97SDavid van Moolenbroek } 2083c38dbb97SDavid van Moolenbroek 2084c38dbb97SDavid van Moolenbroek static void 2085c38dbb97SDavid van Moolenbroek vfs_recvmsg_in(struct trace_proc * proc, const message * m_out, 2086c38dbb97SDavid van Moolenbroek const message * m_in, int failed) 2087c38dbb97SDavid van Moolenbroek { 2088c38dbb97SDavid van Moolenbroek 2089c38dbb97SDavid van Moolenbroek /* 2090c38dbb97SDavid van Moolenbroek * We choose to print only the resulting structure in this case. Doing 2091c38dbb97SDavid van Moolenbroek * so is easier and less messy than printing both the original and the 2092c38dbb97SDavid van Moolenbroek * result for the fields that are updated by the system (msg_namelen 2093c38dbb97SDavid van Moolenbroek * and msg_controllen); also, this approach is stateless. Admittedly 2094c38dbb97SDavid van Moolenbroek * it is not entirely consistent with many other parts of the trace 2095c38dbb97SDavid van Moolenbroek * output, though. 2096c38dbb97SDavid van Moolenbroek */ 2097c38dbb97SDavid van Moolenbroek put_struct_msghdr(proc, "msg", PF_ALT | failed, 2098c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sockmsg.msgbuf, m_in->m_type); 2099c38dbb97SDavid van Moolenbroek put_flags(proc, "flags", msg_flags, COUNT(msg_flags), "0x%x", 2100c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sockmsg.flags); 2101c38dbb97SDavid van Moolenbroek 2102c38dbb97SDavid van Moolenbroek put_equals(proc); 2103c38dbb97SDavid van Moolenbroek put_result(proc); 2104c38dbb97SDavid van Moolenbroek } 2105c38dbb97SDavid van Moolenbroek 2106c38dbb97SDavid van Moolenbroek static void 2107c38dbb97SDavid van Moolenbroek put_sockopt_name(struct trace_proc * proc, const char * name, int level, 2108c38dbb97SDavid van Moolenbroek int optname) 2109c38dbb97SDavid van Moolenbroek { 2110c38dbb97SDavid van Moolenbroek const char *text = NULL; 2111c38dbb97SDavid van Moolenbroek 2112c38dbb97SDavid van Moolenbroek /* 2113c38dbb97SDavid van Moolenbroek * The only level for which we can know names is SOL_SOCKET. See also 2114c38dbb97SDavid van Moolenbroek * put_socket_level(). Of course we could guess, but then we need a 2115c38dbb97SDavid van Moolenbroek * proper guessing system, which should probably also take into account 2116c38dbb97SDavid van Moolenbroek * the [gs]etsockopt option length. TODO. 2117c38dbb97SDavid van Moolenbroek */ 2118c38dbb97SDavid van Moolenbroek if (!valuesonly && level == SOL_SOCKET) { 2119c38dbb97SDavid van Moolenbroek switch (optname) { 2120c38dbb97SDavid van Moolenbroek TEXT(SO_DEBUG); 2121c38dbb97SDavid van Moolenbroek TEXT(SO_ACCEPTCONN); 2122c38dbb97SDavid van Moolenbroek TEXT(SO_REUSEADDR); 2123c38dbb97SDavid van Moolenbroek TEXT(SO_KEEPALIVE); 2124c38dbb97SDavid van Moolenbroek TEXT(SO_DONTROUTE); 2125c38dbb97SDavid van Moolenbroek TEXT(SO_BROADCAST); 2126c38dbb97SDavid van Moolenbroek TEXT(SO_USELOOPBACK); 2127c38dbb97SDavid van Moolenbroek TEXT(SO_LINGER); 2128c38dbb97SDavid van Moolenbroek TEXT(SO_OOBINLINE); 2129c38dbb97SDavid van Moolenbroek TEXT(SO_REUSEPORT); 2130c38dbb97SDavid van Moolenbroek TEXT(SO_NOSIGPIPE); 2131c38dbb97SDavid van Moolenbroek TEXT(SO_TIMESTAMP); 2132c38dbb97SDavid van Moolenbroek TEXT(SO_PASSCRED); 2133c38dbb97SDavid van Moolenbroek TEXT(SO_PEERCRED); 2134c38dbb97SDavid van Moolenbroek TEXT(SO_SNDBUF); 2135c38dbb97SDavid van Moolenbroek TEXT(SO_RCVBUF); 2136c38dbb97SDavid van Moolenbroek TEXT(SO_SNDLOWAT); 2137c38dbb97SDavid van Moolenbroek TEXT(SO_RCVLOWAT); 2138c38dbb97SDavid van Moolenbroek TEXT(SO_ERROR); 2139c38dbb97SDavid van Moolenbroek TEXT(SO_TYPE); 2140c38dbb97SDavid van Moolenbroek TEXT(SO_OVERFLOWED); 2141c38dbb97SDavid van Moolenbroek TEXT(SO_NOHEADER); 2142c38dbb97SDavid van Moolenbroek TEXT(SO_SNDTIMEO); 2143c38dbb97SDavid van Moolenbroek TEXT(SO_RCVTIMEO); 2144c38dbb97SDavid van Moolenbroek } 2145c38dbb97SDavid van Moolenbroek } 2146c38dbb97SDavid van Moolenbroek 2147c38dbb97SDavid van Moolenbroek if (text != NULL) 2148c38dbb97SDavid van Moolenbroek put_field(proc, name, text); 2149c38dbb97SDavid van Moolenbroek else 2150c38dbb97SDavid van Moolenbroek put_value(proc, name, "0x%x", optname); 2151c38dbb97SDavid van Moolenbroek } 2152c38dbb97SDavid van Moolenbroek 2153c38dbb97SDavid van Moolenbroek static void 2154c38dbb97SDavid van Moolenbroek put_sockopt_data(struct trace_proc * proc, const char * name, int flags, 2155c38dbb97SDavid van Moolenbroek int level, int optname, vir_bytes addr, socklen_t len) 2156c38dbb97SDavid van Moolenbroek { 2157c38dbb97SDavid van Moolenbroek const char *text; 2158c38dbb97SDavid van Moolenbroek int i; 2159c38dbb97SDavid van Moolenbroek struct linger l; 2160c38dbb97SDavid van Moolenbroek struct uucred cr; 2161c38dbb97SDavid van Moolenbroek struct timeval tv; 2162c38dbb97SDavid van Moolenbroek void *ptr; 2163c38dbb97SDavid van Moolenbroek size_t size; 2164c38dbb97SDavid van Moolenbroek 2165c38dbb97SDavid van Moolenbroek /* See above regarding ambiguity for levels other than SOL_SOCKET. */ 2166c38dbb97SDavid van Moolenbroek if ((flags & PF_FAILED) || valuesonly > 1 || len == 0 || 2167c38dbb97SDavid van Moolenbroek level != SOL_SOCKET) { 2168c38dbb97SDavid van Moolenbroek put_ptr(proc, name, addr); 2169c38dbb97SDavid van Moolenbroek 2170c38dbb97SDavid van Moolenbroek return; 2171c38dbb97SDavid van Moolenbroek } 2172c38dbb97SDavid van Moolenbroek 2173c38dbb97SDavid van Moolenbroek /* Determine how much data to get, and where to put it. */ 2174c38dbb97SDavid van Moolenbroek switch (optname) { 2175c38dbb97SDavid van Moolenbroek case SO_DEBUG: 2176c38dbb97SDavid van Moolenbroek case SO_ACCEPTCONN: 2177c38dbb97SDavid van Moolenbroek case SO_REUSEADDR: 2178c38dbb97SDavid van Moolenbroek case SO_KEEPALIVE: 2179c38dbb97SDavid van Moolenbroek case SO_DONTROUTE: 2180c38dbb97SDavid van Moolenbroek case SO_BROADCAST: 2181c38dbb97SDavid van Moolenbroek case SO_USELOOPBACK: 2182c38dbb97SDavid van Moolenbroek case SO_OOBINLINE: 2183c38dbb97SDavid van Moolenbroek case SO_REUSEPORT: 2184c38dbb97SDavid van Moolenbroek case SO_NOSIGPIPE: 2185c38dbb97SDavid van Moolenbroek case SO_TIMESTAMP: 2186c38dbb97SDavid van Moolenbroek case SO_PASSCRED: 2187c38dbb97SDavid van Moolenbroek case SO_SNDBUF: 2188c38dbb97SDavid van Moolenbroek case SO_RCVBUF: 2189c38dbb97SDavid van Moolenbroek case SO_SNDLOWAT: 2190c38dbb97SDavid van Moolenbroek case SO_RCVLOWAT: 2191c38dbb97SDavid van Moolenbroek case SO_ERROR: 2192c38dbb97SDavid van Moolenbroek case SO_TYPE: 2193c38dbb97SDavid van Moolenbroek case SO_OVERFLOWED: 2194c38dbb97SDavid van Moolenbroek case SO_NOHEADER: 2195c38dbb97SDavid van Moolenbroek ptr = &i; 2196c38dbb97SDavid van Moolenbroek size = sizeof(i); 2197c38dbb97SDavid van Moolenbroek break; 2198c38dbb97SDavid van Moolenbroek case SO_LINGER: 2199c38dbb97SDavid van Moolenbroek ptr = &l; 2200c38dbb97SDavid van Moolenbroek size = sizeof(l); 2201c38dbb97SDavid van Moolenbroek break; 2202c38dbb97SDavid van Moolenbroek case SO_PEERCRED: 2203c38dbb97SDavid van Moolenbroek ptr = &cr; 2204c38dbb97SDavid van Moolenbroek size = sizeof(cr); 2205c38dbb97SDavid van Moolenbroek break; 2206c38dbb97SDavid van Moolenbroek case SO_SNDTIMEO: 2207c38dbb97SDavid van Moolenbroek case SO_RCVTIMEO: 2208c38dbb97SDavid van Moolenbroek ptr = &tv; 2209c38dbb97SDavid van Moolenbroek size = sizeof(tv); 2210c38dbb97SDavid van Moolenbroek break; 2211c38dbb97SDavid van Moolenbroek default: 2212c38dbb97SDavid van Moolenbroek put_ptr(proc, name, addr); 2213c38dbb97SDavid van Moolenbroek return; 2214c38dbb97SDavid van Moolenbroek } 2215c38dbb97SDavid van Moolenbroek 2216c38dbb97SDavid van Moolenbroek /* Get the data. Do not bother with truncated values. */ 2217c38dbb97SDavid van Moolenbroek if (len < size || mem_get_data(proc->pid, addr, ptr, size) < 0) { 2218c38dbb97SDavid van Moolenbroek put_ptr(proc, name, addr); 2219c38dbb97SDavid van Moolenbroek 2220c38dbb97SDavid van Moolenbroek return; 2221c38dbb97SDavid van Moolenbroek } 2222c38dbb97SDavid van Moolenbroek 2223c38dbb97SDavid van Moolenbroek /* Print the data according to the option name. */ 2224c38dbb97SDavid van Moolenbroek switch (optname) { 2225c38dbb97SDavid van Moolenbroek case SO_LINGER: 2226c38dbb97SDavid van Moolenbroek /* This isn't going to appear anywhere else; do it inline. */ 2227c38dbb97SDavid van Moolenbroek put_open(proc, name, 0, "{", ", "); 2228c38dbb97SDavid van Moolenbroek put_value(proc, "l_onoff", "%d", l.l_onoff); 2229c38dbb97SDavid van Moolenbroek put_value(proc, "l_linger", "%d", l.l_linger); 2230c38dbb97SDavid van Moolenbroek put_close(proc, "}"); 2231c38dbb97SDavid van Moolenbroek break; 2232c38dbb97SDavid van Moolenbroek case SO_PEERCRED: 2233c38dbb97SDavid van Moolenbroek put_struct_uucred(proc, name, PF_LOCADDR, (vir_bytes)&cr); 2234c38dbb97SDavid van Moolenbroek break; 2235c38dbb97SDavid van Moolenbroek case SO_ERROR: 2236c38dbb97SDavid van Moolenbroek put_open(proc, name, 0, "{", ", "); 2237c38dbb97SDavid van Moolenbroek if (!valuesonly && (text = get_error_name(i)) != NULL) 2238c38dbb97SDavid van Moolenbroek put_field(proc, NULL, text); 2239c38dbb97SDavid van Moolenbroek else 2240c38dbb97SDavid van Moolenbroek put_value(proc, NULL, "%d", i); 2241c38dbb97SDavid van Moolenbroek put_close(proc, "}"); 2242c38dbb97SDavid van Moolenbroek break; 2243c38dbb97SDavid van Moolenbroek case SO_TYPE: 2244c38dbb97SDavid van Moolenbroek put_open(proc, name, 0, "{", ", "); 2245c38dbb97SDavid van Moolenbroek put_socket_type(proc, NULL, i); 2246c38dbb97SDavid van Moolenbroek put_close(proc, "}"); 2247c38dbb97SDavid van Moolenbroek break; 2248c38dbb97SDavid van Moolenbroek case SO_SNDTIMEO: 2249c38dbb97SDavid van Moolenbroek case SO_RCVTIMEO: 2250c38dbb97SDavid van Moolenbroek put_struct_timeval(proc, name, PF_LOCADDR, (vir_bytes)&tv); 2251c38dbb97SDavid van Moolenbroek break; 2252c38dbb97SDavid van Moolenbroek default: 2253c38dbb97SDavid van Moolenbroek /* All other options are integer values. */ 2254c38dbb97SDavid van Moolenbroek put_value(proc, name, "{%d}", i); 2255c38dbb97SDavid van Moolenbroek } 2256c38dbb97SDavid van Moolenbroek } 2257c38dbb97SDavid van Moolenbroek 2258c38dbb97SDavid van Moolenbroek static int 2259c38dbb97SDavid van Moolenbroek vfs_setsockopt_out(struct trace_proc * proc, const message * m_out) 2260c38dbb97SDavid van Moolenbroek { 2261c38dbb97SDavid van Moolenbroek int level, name; 2262c38dbb97SDavid van Moolenbroek 2263c38dbb97SDavid van Moolenbroek level = m_out->m_lc_vfs_sockopt.level; 2264c38dbb97SDavid van Moolenbroek name = m_out->m_lc_vfs_sockopt.name; 2265c38dbb97SDavid van Moolenbroek 2266c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sockopt.fd); 2267c38dbb97SDavid van Moolenbroek put_socket_level(proc, "level", level); 2268c38dbb97SDavid van Moolenbroek put_sockopt_name(proc, "name", level, name); 2269c38dbb97SDavid van Moolenbroek put_sockopt_data(proc, "buf", 0, level, name, 2270c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sockopt.buf, m_out->m_lc_vfs_sockopt.len); 2271c38dbb97SDavid van Moolenbroek put_value(proc, "len", "%u", m_out->m_lc_vfs_sockopt.len); 2272c38dbb97SDavid van Moolenbroek 2273c38dbb97SDavid van Moolenbroek return CT_DONE; 2274c38dbb97SDavid van Moolenbroek } 2275c38dbb97SDavid van Moolenbroek 2276c38dbb97SDavid van Moolenbroek static int 2277c38dbb97SDavid van Moolenbroek vfs_getsockopt_out(struct trace_proc * proc, const message * m_out) 2278c38dbb97SDavid van Moolenbroek { 2279c38dbb97SDavid van Moolenbroek int level; 2280c38dbb97SDavid van Moolenbroek 2281c38dbb97SDavid van Moolenbroek level = m_out->m_lc_vfs_sockopt.level; 2282c38dbb97SDavid van Moolenbroek 2283c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sockopt.fd); 2284c38dbb97SDavid van Moolenbroek put_socket_level(proc, "level", level); 2285c38dbb97SDavid van Moolenbroek put_sockopt_name(proc, "name", level, m_out->m_lc_vfs_sockopt.name); 2286c38dbb97SDavid van Moolenbroek 2287c38dbb97SDavid van Moolenbroek return CT_NOTDONE; 2288c38dbb97SDavid van Moolenbroek } 2289c38dbb97SDavid van Moolenbroek 2290c38dbb97SDavid van Moolenbroek static void 2291c38dbb97SDavid van Moolenbroek vfs_getsockopt_in(struct trace_proc * proc, const message * m_out, 2292c38dbb97SDavid van Moolenbroek const message * m_in, int failed) 2293c38dbb97SDavid van Moolenbroek { 2294c38dbb97SDavid van Moolenbroek 2295c38dbb97SDavid van Moolenbroek put_sockopt_data(proc, "buf", failed, m_out->m_lc_vfs_sockopt.level, 2296c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sockopt.name, m_out->m_lc_vfs_sockopt.buf, 2297c38dbb97SDavid van Moolenbroek m_in->m_vfs_lc_socklen.len); 2298c38dbb97SDavid van Moolenbroek /* 2299c38dbb97SDavid van Moolenbroek * For the length, we follow the same scheme as for addr_len pointers 2300c38dbb97SDavid van Moolenbroek * in accept() et al., in that we print the result only. We need not 2301c38dbb97SDavid van Moolenbroek * take into account that the given buffer is NULL as it must not be. 2302c38dbb97SDavid van Moolenbroek */ 2303c38dbb97SDavid van Moolenbroek if (!failed) 2304c38dbb97SDavid van Moolenbroek put_value(proc, "len", "%u", m_out->m_lc_vfs_sockopt.len); 2305c38dbb97SDavid van Moolenbroek else 2306c38dbb97SDavid van Moolenbroek put_field(proc, "len", "&.."); 2307c38dbb97SDavid van Moolenbroek 2308c38dbb97SDavid van Moolenbroek put_equals(proc); 2309c38dbb97SDavid van Moolenbroek put_result(proc); 2310c38dbb97SDavid van Moolenbroek } 2311c38dbb97SDavid van Moolenbroek 2312c38dbb97SDavid van Moolenbroek /* This function is shared between getsockname and getpeername. */ 2313c38dbb97SDavid van Moolenbroek static int 2314c38dbb97SDavid van Moolenbroek vfs_getsockname_out(struct trace_proc * proc, const message * m_out) 2315c38dbb97SDavid van Moolenbroek { 2316c38dbb97SDavid van Moolenbroek 2317c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_sockaddr.fd); 2318c38dbb97SDavid van Moolenbroek 2319c38dbb97SDavid van Moolenbroek return CT_NOTDONE; 2320c38dbb97SDavid van Moolenbroek } 2321c38dbb97SDavid van Moolenbroek 2322c38dbb97SDavid van Moolenbroek static void 2323c38dbb97SDavid van Moolenbroek vfs_getsockname_in(struct trace_proc * proc, const message * m_out, 2324c38dbb97SDavid van Moolenbroek const message * m_in, int failed) 2325c38dbb97SDavid van Moolenbroek { 2326c38dbb97SDavid van Moolenbroek 2327c38dbb97SDavid van Moolenbroek put_struct_sockaddr(proc, "addr", failed, 2328c38dbb97SDavid van Moolenbroek m_out->m_lc_vfs_sockaddr.addr, m_in->m_vfs_lc_socklen.len); 2329c38dbb97SDavid van Moolenbroek if (m_out->m_lc_vfs_sockaddr.addr == 0) 2330c38dbb97SDavid van Moolenbroek put_field(proc, "addr_len", "NULL"); 2331c38dbb97SDavid van Moolenbroek else if (!failed) 2332c38dbb97SDavid van Moolenbroek put_value(proc, "addr_len", "{%u}", 2333c38dbb97SDavid van Moolenbroek m_in->m_vfs_lc_socklen.len); 2334c38dbb97SDavid van Moolenbroek else 2335c38dbb97SDavid van Moolenbroek put_field(proc, "addr_len", "&.."); 2336c38dbb97SDavid van Moolenbroek 2337c38dbb97SDavid van Moolenbroek put_equals(proc); 2338c38dbb97SDavid van Moolenbroek put_result(proc); 2339c38dbb97SDavid van Moolenbroek } 2340c38dbb97SDavid van Moolenbroek 2341c38dbb97SDavid van Moolenbroek void 2342c38dbb97SDavid van Moolenbroek put_shutdown_how(struct trace_proc * proc, const char * name, int how) 2343c38dbb97SDavid van Moolenbroek { 2344c38dbb97SDavid van Moolenbroek const char *text = NULL; 2345c38dbb97SDavid van Moolenbroek 2346c38dbb97SDavid van Moolenbroek if (!valuesonly) { 2347c38dbb97SDavid van Moolenbroek switch (how) { 2348c38dbb97SDavid van Moolenbroek TEXT(SHUT_RD); 2349c38dbb97SDavid van Moolenbroek TEXT(SHUT_WR); 2350c38dbb97SDavid van Moolenbroek TEXT(SHUT_RDWR); 2351c38dbb97SDavid van Moolenbroek } 2352c38dbb97SDavid van Moolenbroek } 2353c38dbb97SDavid van Moolenbroek 2354c38dbb97SDavid van Moolenbroek if (text != NULL) 2355c38dbb97SDavid van Moolenbroek put_field(proc, name, text); 2356c38dbb97SDavid van Moolenbroek else 2357c38dbb97SDavid van Moolenbroek put_value(proc, name, "%d", how); 2358c38dbb97SDavid van Moolenbroek } 2359c38dbb97SDavid van Moolenbroek 2360c38dbb97SDavid van Moolenbroek static int 2361c38dbb97SDavid van Moolenbroek vfs_shutdown_out(struct trace_proc * proc, const message * m_out) 2362c38dbb97SDavid van Moolenbroek { 2363c38dbb97SDavid van Moolenbroek 2364c38dbb97SDavid van Moolenbroek put_fd(proc, "fd", m_out->m_lc_vfs_shutdown.fd); 2365c38dbb97SDavid van Moolenbroek put_shutdown_how(proc, "how", m_out->m_lc_vfs_shutdown.how); 2366c38dbb97SDavid van Moolenbroek 2367c38dbb97SDavid van Moolenbroek return CT_DONE; 2368c38dbb97SDavid van Moolenbroek } 2369c38dbb97SDavid van Moolenbroek 2370521fa314SDavid van Moolenbroek #define VFS_CALL(c) [((VFS_ ## c) - VFS_BASE)] 2371521fa314SDavid van Moolenbroek 2372521fa314SDavid van Moolenbroek static const struct call_handler vfs_map[] = { 2373521fa314SDavid van Moolenbroek VFS_CALL(READ) = HANDLER("read", vfs_read_out, vfs_read_in), 2374521fa314SDavid van Moolenbroek VFS_CALL(WRITE) = HANDLER("write", vfs_write_out, default_in), 2375521fa314SDavid van Moolenbroek VFS_CALL(LSEEK) = HANDLER("lseek", vfs_lseek_out, vfs_lseek_in), 2376521fa314SDavid van Moolenbroek VFS_CALL(OPEN) = HANDLER("open", vfs_open_out, vfs_open_in), 2377521fa314SDavid van Moolenbroek VFS_CALL(CREAT) = HANDLER("open", vfs_creat_out, vfs_open_in), 2378521fa314SDavid van Moolenbroek VFS_CALL(CLOSE) = HANDLER("close", vfs_close_out, default_in), 2379521fa314SDavid van Moolenbroek VFS_CALL(LINK) = HANDLER("link", vfs_link_out, default_in), 2380521fa314SDavid van Moolenbroek VFS_CALL(UNLINK) = HANDLER("unlink", vfs_path_out, default_in), 2381521fa314SDavid van Moolenbroek VFS_CALL(CHDIR) = HANDLER("chdir", vfs_path_out, default_in), 2382521fa314SDavid van Moolenbroek VFS_CALL(MKDIR) = HANDLER("mkdir", vfs_path_mode_out, default_in), 2383521fa314SDavid van Moolenbroek VFS_CALL(MKNOD) = HANDLER("mknod", vfs_mknod_out, default_in), 2384521fa314SDavid van Moolenbroek VFS_CALL(CHMOD) = HANDLER("chmod", vfs_path_mode_out, default_in), 2385521fa314SDavid van Moolenbroek VFS_CALL(CHOWN) = HANDLER("chown", vfs_chown_out, default_in), 2386521fa314SDavid van Moolenbroek VFS_CALL(MOUNT) = HANDLER("mount", vfs_mount_out, default_in), 2387521fa314SDavid van Moolenbroek VFS_CALL(UMOUNT) = HANDLER("umount", vfs_umount_out, vfs_umount_in), 2388521fa314SDavid van Moolenbroek VFS_CALL(ACCESS) = HANDLER("access", vfs_access_out, default_in), 2389521fa314SDavid van Moolenbroek VFS_CALL(SYNC) = HANDLER("sync", default_out, default_in), 2390521fa314SDavid van Moolenbroek VFS_CALL(RENAME) = HANDLER("rename", vfs_link_out, default_in), 2391521fa314SDavid van Moolenbroek VFS_CALL(RMDIR) = HANDLER("rmdir", vfs_path_out, default_in), 2392521fa314SDavid van Moolenbroek VFS_CALL(SYMLINK) = HANDLER("symlink", vfs_link_out, default_in), 2393521fa314SDavid van Moolenbroek VFS_CALL(READLINK) = HANDLER("readlink", vfs_readlink_out, 2394521fa314SDavid van Moolenbroek vfs_readlink_in), 2395521fa314SDavid van Moolenbroek VFS_CALL(STAT) = HANDLER("stat", vfs_stat_out, vfs_stat_in), 2396521fa314SDavid van Moolenbroek VFS_CALL(FSTAT) = HANDLER("fstat", vfs_fstat_out, vfs_fstat_in), 2397521fa314SDavid van Moolenbroek VFS_CALL(LSTAT) = HANDLER("lstat", vfs_stat_out, vfs_stat_in), 2398521fa314SDavid van Moolenbroek VFS_CALL(IOCTL) = HANDLER("ioctl", vfs_ioctl_out, vfs_ioctl_in), 2399521fa314SDavid van Moolenbroek VFS_CALL(FCNTL) = HANDLER("fcntl", vfs_fcntl_out, vfs_fcntl_in), 2400521fa314SDavid van Moolenbroek VFS_CALL(PIPE2) = HANDLER("pipe2", vfs_pipe2_out, vfs_pipe2_in), 2401521fa314SDavid van Moolenbroek VFS_CALL(UMASK) = HANDLER("umask", vfs_umask_out, vfs_umask_in), 2402521fa314SDavid van Moolenbroek VFS_CALL(CHROOT) = HANDLER("chroot", vfs_path_out, default_in), 2403521fa314SDavid van Moolenbroek VFS_CALL(GETDENTS) = HANDLER("getdents", vfs_getdents_out, 2404521fa314SDavid van Moolenbroek vfs_getdents_in), 2405521fa314SDavid van Moolenbroek VFS_CALL(SELECT) = HANDLER("select", vfs_select_out, vfs_select_in), 2406521fa314SDavid van Moolenbroek VFS_CALL(FCHDIR) = HANDLER("fchdir", vfs_fchdir_out, default_in), 2407521fa314SDavid van Moolenbroek VFS_CALL(FSYNC) = HANDLER("fsync", vfs_fsync_out, default_in), 2408521fa314SDavid van Moolenbroek VFS_CALL(TRUNCATE) = HANDLER("truncate", vfs_truncate_out, default_in), 2409521fa314SDavid van Moolenbroek VFS_CALL(FTRUNCATE) = HANDLER("ftruncate", vfs_ftruncate_out, 2410521fa314SDavid van Moolenbroek default_in), 2411521fa314SDavid van Moolenbroek VFS_CALL(FCHMOD) = HANDLER("fchmod", vfs_fchmod_out, default_in), 2412521fa314SDavid van Moolenbroek VFS_CALL(FCHOWN) = HANDLER("fchown", vfs_fchown_out, default_in), 2413521fa314SDavid van Moolenbroek VFS_CALL(UTIMENS) = HANDLER_NAME(vfs_utimens_name, vfs_utimens_out, 2414521fa314SDavid van Moolenbroek default_in), 2415521fa314SDavid van Moolenbroek VFS_CALL(GETVFSSTAT) = HANDLER("getvfsstat", vfs_getvfsstat_out, 2416521fa314SDavid van Moolenbroek vfs_getvfsstat_in), 2417521fa314SDavid van Moolenbroek VFS_CALL(STATVFS1) = HANDLER("statvfs1", vfs_statvfs1_out, 2418521fa314SDavid van Moolenbroek vfs_statvfs1_in), 2419521fa314SDavid van Moolenbroek VFS_CALL(FSTATVFS1) = HANDLER("fstatvfs1", vfs_fstatvfs1_out, 2420521fa314SDavid van Moolenbroek vfs_statvfs1_in), 2421521fa314SDavid van Moolenbroek VFS_CALL(SVRCTL) = HANDLER("vfs_svrctl", vfs_svrctl_out, 2422521fa314SDavid van Moolenbroek vfs_svrctl_in), 2423521fa314SDavid van Moolenbroek VFS_CALL(GCOV_FLUSH) = HANDLER("gcov_flush", vfs_gcov_flush_out, 2424521fa314SDavid van Moolenbroek default_in), 2425c38dbb97SDavid van Moolenbroek VFS_CALL(SOCKET) = HANDLER("socket", vfs_socket_out, default_in), 2426c38dbb97SDavid van Moolenbroek VFS_CALL(SOCKETPAIR) = HANDLER("socketpair", vfs_socketpair_out, 2427c38dbb97SDavid van Moolenbroek vfs_socketpair_in), 2428c38dbb97SDavid van Moolenbroek VFS_CALL(BIND) = HANDLER("bind", vfs_bind_out, default_in), 2429c38dbb97SDavid van Moolenbroek VFS_CALL(CONNECT) = HANDLER("connect", vfs_bind_out, default_in), 2430c38dbb97SDavid van Moolenbroek VFS_CALL(LISTEN) = HANDLER("listen", vfs_listen_out, default_in), 2431c38dbb97SDavid van Moolenbroek VFS_CALL(ACCEPT) = HANDLER("accept", vfs_accept_out, vfs_accept_in), 2432c38dbb97SDavid van Moolenbroek VFS_CALL(SENDTO) = HANDLER("sendto", vfs_sendto_out, default_in), 2433c38dbb97SDavid van Moolenbroek VFS_CALL(SENDMSG) = HANDLER("sendmsg", vfs_sendmsg_out, default_in), 2434c38dbb97SDavid van Moolenbroek VFS_CALL(RECVFROM) = HANDLER("recvfrom", vfs_recvfrom_out, 2435c38dbb97SDavid van Moolenbroek vfs_recvfrom_in), 2436c38dbb97SDavid van Moolenbroek VFS_CALL(RECVMSG) = HANDLER("recvmsg", vfs_recvmsg_out, 2437c38dbb97SDavid van Moolenbroek vfs_recvmsg_in), 2438c38dbb97SDavid van Moolenbroek VFS_CALL(SETSOCKOPT) = HANDLER("setsockopt", vfs_setsockopt_out, 2439c38dbb97SDavid van Moolenbroek default_in), 2440c38dbb97SDavid van Moolenbroek VFS_CALL(GETSOCKOPT) = HANDLER("getsockopt", vfs_getsockopt_out, 2441c38dbb97SDavid van Moolenbroek vfs_getsockopt_in), 2442c38dbb97SDavid van Moolenbroek VFS_CALL(GETSOCKNAME) = HANDLER("getsockname", vfs_getsockname_out, 2443c38dbb97SDavid van Moolenbroek vfs_getsockname_in), 2444c38dbb97SDavid van Moolenbroek VFS_CALL(GETPEERNAME) = HANDLER("getpeername", vfs_getsockname_out, 2445c38dbb97SDavid van Moolenbroek vfs_getsockname_in), 2446c38dbb97SDavid van Moolenbroek VFS_CALL(SHUTDOWN) = HANDLER("shutdown", vfs_shutdown_out, default_in), 2447521fa314SDavid van Moolenbroek }; 2448521fa314SDavid van Moolenbroek 2449521fa314SDavid van Moolenbroek const struct calls vfs_calls = { 2450521fa314SDavid van Moolenbroek .endpt = VFS_PROC_NR, 2451521fa314SDavid van Moolenbroek .base = VFS_BASE, 2452521fa314SDavid van Moolenbroek .map = vfs_map, 2453521fa314SDavid van Moolenbroek .count = COUNT(vfs_map) 2454521fa314SDavid van Moolenbroek }; 2455