Annotation of src/usr.bin/kdump/kdump.c, Revision 1.56
1.56 ! deraadt 1: /* $OpenBSD: kdump.c,v 1.55 2011/07/08 19:29:44 otto Exp $ */
1.4 deraadt 2:
1.1 deraadt 3: /*-
4: * Copyright (c) 1988, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.21 millert 15: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
32: #include <sys/param.h>
33: #include <sys/time.h>
34: #include <sys/uio.h>
35: #include <sys/ktrace.h>
36: #include <sys/ioctl.h>
37: #include <sys/ptrace.h>
1.51 otto 38: #include <sys/socket.h>
1.28 deraadt 39: #include <sys/sysctl.h>
1.55 otto 40: #include <sys/socket.h>
41: #include <sys/un.h>
42: #include <sys/stat.h>
43: #include <netinet/in.h>
44: #include <arpa/inet.h>
1.1 deraadt 45: #define _KERNEL
46: #include <sys/errno.h>
47: #undef _KERNEL
48:
1.33 tedu 49: #include <ctype.h>
1.1 deraadt 50: #include <err.h>
51: #include <signal.h>
52: #include <stdio.h>
53: #include <stdlib.h>
1.55 otto 54: #include <stdint.h>
1.1 deraadt 55: #include <string.h>
1.55 otto 56: #include <grp.h>
57: #include <pwd.h>
1.1 deraadt 58: #include <unistd.h>
59: #include <vis.h>
60:
61: #include "ktrace.h"
1.22 deraadt 62: #include "kdump.h"
1.51 otto 63: #include "kdump_subr.h"
1.12 espie 64: #include "extern.h"
1.1 deraadt 65:
1.55 otto 66: int timestamp, decimal, iohex, fancy = 1, tail, maxdata, resolv;
1.1 deraadt 67: char *tracefile = DEF_TRACEFILE;
68: struct ktr_header ktr_header;
1.17 deraadt 69: pid_t pid = -1;
1.1 deraadt 70:
1.55 otto 71: #define TIME_FORMAT "%b %e %T %Y"
1.1 deraadt 72: #define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
73:
74: #include <sys/syscall.h>
75:
1.25 mickey 76: #include <compat/linux/linux_syscall.h>
1.1 deraadt 77:
78: #define KTRACE
1.19 mickey 79: #define PTRACE
1.7 deraadt 80: #define NFSCLIENT
81: #define NFSSERVER
82: #define SYSVSEM
83: #define SYSVMSG
84: #define SYSVSHM
85: #define LFS
1.25 mickey 86: #include <kern/syscalls.c>
1.1 deraadt 87:
1.25 mickey 88: #include <compat/linux/linux_syscalls.c>
1.1 deraadt 89: #undef KTRACE
1.19 mickey 90: #undef PTRACE
1.7 deraadt 91: #undef NFSCLIENT
92: #undef NFSSERVER
93: #undef SYSVSEM
94: #undef SYSVMSG
95: #undef SYSVSHM
96: #undef LFS
1.1 deraadt 97:
98: struct emulation {
99: char *name; /* Emulation name */
100: char **sysnames; /* Array of system call names */
101: int nsysnames; /* Number of */
102: };
103:
104: static struct emulation emulations[] = {
1.9 deraadt 105: { "native", syscallnames, SYS_MAXSYSCALL },
106: { "linux", linux_syscallnames, LINUX_SYS_MAXSYSCALL },
1.49 miod 107: { NULL, NULL, 0 }
1.1 deraadt 108: };
109:
110: struct emulation *current;
111:
112:
113: static char *ptrace_ops[] = {
114: "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U",
115: "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE",
1.15 art 116: "PT_KILL", "PT_ATTACH", "PT_DETACH", "PT_IO",
1.1 deraadt 117: };
118:
1.52 otto 119: static int narg;
120: static register_t *ap;
121: static char sep;
122:
1.37 tedu 123: static int fread_tail(void *, size_t, size_t);
1.13 millert 124: static void dumpheader(struct ktr_header *);
125: static void ktrcsw(struct ktr_csw *);
1.37 tedu 126: static void ktremul(char *, size_t);
127: static void ktrgenio(struct ktr_genio *, size_t);
128: static void ktrnamei(const char *, size_t);
1.13 millert 129: static void ktrpsig(struct ktr_psig *);
130: static void ktrsyscall(struct ktr_syscall *);
131: static void ktrsysret(struct ktr_sysret *);
1.55 otto 132: static void ktrstruct(char *, size_t);
1.13 millert 133: static void setemul(const char *);
134: static void usage(void);
1.12 espie 135:
1.1 deraadt 136: int
1.17 deraadt 137: main(int argc, char *argv[])
1.1 deraadt 138: {
1.37 tedu 139: int ch, silent;
140: size_t ktrlen, size;
1.17 deraadt 141: int trpoints = ALL_POINTS;
1.12 espie 142: void *m;
1.1 deraadt 143:
1.3 deraadt 144: current = &emulations[0]; /* native */
1.1 deraadt 145:
1.55 otto 146: while ((ch = getopt(argc, argv, "e:f:dlm:nrRp:Tt:xX")) != -1)
1.1 deraadt 147: switch (ch) {
148: case 'e':
149: setemul(optarg);
150: break;
151: case 'f':
152: tracefile = optarg;
153: break;
154: case 'd':
155: decimal = 1;
156: break;
157: case 'l':
158: tail = 1;
159: break;
160: case 'm':
161: maxdata = atoi(optarg);
162: break;
163: case 'n':
164: fancy = 0;
165: break;
1.17 deraadt 166: case 'p':
167: pid = atoi(optarg);
168: break;
1.55 otto 169: case 'r':
170: resolv = 1;
171: break;
1.1 deraadt 172: case 'R':
173: timestamp = 2; /* relative timestamp */
174: break;
175: case 'T':
176: timestamp = 1;
177: break;
178: case 't':
179: trpoints = getpoints(optarg);
180: if (trpoints < 0)
181: errx(1, "unknown trace point in %s", optarg);
182: break;
1.31 tedu 183: case 'x':
184: iohex = 1;
185: break;
186: case 'X':
187: iohex = 2;
188: break;
1.1 deraadt 189: default:
190: usage();
191: }
1.5 deraadt 192: if (argc > optind)
1.1 deraadt 193: usage();
194:
1.37 tedu 195: m = malloc(size = 1025);
1.1 deraadt 196: if (m == NULL)
1.37 tedu 197: err(1, NULL);
1.1 deraadt 198: if (!freopen(tracefile, "r", stdin))
199: err(1, "%s", tracefile);
200: while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
1.17 deraadt 201: silent = 0;
202: if (pid != -1 && pid != ktr_header.ktr_pid)
203: silent = 1;
204: if (silent == 0 && trpoints & (1<<ktr_header.ktr_type))
1.1 deraadt 205: dumpheader(&ktr_header);
1.37 tedu 206: ktrlen = ktr_header.ktr_len;
1.1 deraadt 207: if (ktrlen > size) {
1.23 tedu 208: void *newm;
209:
210: newm = realloc(m, ktrlen+1);
211: if (newm == NULL)
1.37 tedu 212: err(1, NULL);
1.23 tedu 213: m = newm;
1.1 deraadt 214: size = ktrlen;
215: }
216: if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
217: errx(1, "data too short");
1.17 deraadt 218: if (silent)
219: continue;
1.1 deraadt 220: if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
221: continue;
222: switch (ktr_header.ktr_type) {
223: case KTR_SYSCALL:
224: ktrsyscall((struct ktr_syscall *)m);
225: break;
226: case KTR_SYSRET:
227: ktrsysret((struct ktr_sysret *)m);
228: break;
229: case KTR_NAMEI:
230: ktrnamei(m, ktrlen);
231: break;
232: case KTR_GENIO:
233: ktrgenio((struct ktr_genio *)m, ktrlen);
234: break;
235: case KTR_PSIG:
236: ktrpsig((struct ktr_psig *)m);
237: break;
238: case KTR_CSW:
239: ktrcsw((struct ktr_csw *)m);
240: break;
241: case KTR_EMUL:
242: ktremul(m, ktrlen);
243: break;
1.55 otto 244: case KTR_STRUCT:
245: ktrstruct(m, ktrlen);
246: break;
1.1 deraadt 247: }
248: if (tail)
249: (void)fflush(stdout);
250: }
1.12 espie 251: exit(0);
1.1 deraadt 252: }
253:
1.12 espie 254: static int
1.37 tedu 255: fread_tail(void *buf, size_t size, size_t num)
1.1 deraadt 256: {
257: int i;
258:
259: while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
260: (void)sleep(1);
261: clearerr(stdin);
262: }
263: return (i);
264: }
265:
1.12 espie 266: static void
1.17 deraadt 267: dumpheader(struct ktr_header *kth)
1.1 deraadt 268: {
1.17 deraadt 269: static struct timeval prevtime;
1.1 deraadt 270: char unknown[64], *type;
271: struct timeval temp;
272:
273: switch (kth->ktr_type) {
274: case KTR_SYSCALL:
275: type = "CALL";
276: break;
277: case KTR_SYSRET:
278: type = "RET ";
279: break;
280: case KTR_NAMEI:
281: type = "NAMI";
282: break;
283: case KTR_GENIO:
284: type = "GIO ";
285: break;
286: case KTR_PSIG:
287: type = "PSIG";
288: break;
289: case KTR_CSW:
290: type = "CSW";
291: break;
292: case KTR_EMUL:
293: type = "EMUL";
294: break;
1.55 otto 295: case KTR_STRUCT:
296: type = "STRU";
297: break;
1.1 deraadt 298: default:
1.17 deraadt 299: (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)",
300: kth->ktr_type);
1.1 deraadt 301: type = unknown;
302: }
303:
1.16 mpech 304: (void)printf("%6ld %-8.*s ", (long)kth->ktr_pid, MAXCOMLEN,
305: kth->ktr_comm);
1.1 deraadt 306: if (timestamp) {
307: if (timestamp == 2) {
308: timersub(&kth->ktr_time, &prevtime, &temp);
309: prevtime = kth->ktr_time;
310: } else
311: temp = kth->ktr_time;
312: (void)printf("%ld.%06ld ", temp.tv_sec, temp.tv_usec);
313: }
314: (void)printf("%s ", type);
315: }
316:
1.12 espie 317: static void
1.17 deraadt 318: ioctldecode(u_long cmd)
1.2 deraadt 319: {
320: char dirbuf[4], *dir = dirbuf;
321:
1.6 deraadt 322: if (cmd & IOC_IN)
323: *dir++ = 'W';
1.2 deraadt 324: if (cmd & IOC_OUT)
325: *dir++ = 'R';
326: *dir = '\0';
327:
1.33 tedu 328: printf(decimal ? ",_IO%s('%c',%lu" : ",_IO%s('%c',%#lx",
329: dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1.2 deraadt 330: if ((cmd & IOC_VOID) == 0)
1.34 tedu 331: printf(decimal ? ",%lu)" : ",%#lx)", (cmd >> 16) & 0xff);
1.2 deraadt 332: else
333: printf(")");
334: }
1.1 deraadt 335:
1.52 otto 336: static void
337: ptracedecode(void)
338: {
339: if (*ap >= 0 && *ap <
340: sizeof(ptrace_ops) / sizeof(ptrace_ops[0]))
341: (void)printf("%s", ptrace_ops[*ap]);
342: else switch(*ap) {
343: #ifdef PT_GETFPREGS
344: case PT_GETFPREGS:
345: (void)printf("PT_GETFPREGS");
346: break;
347: #endif
348: case PT_GETREGS:
349: (void)printf("PT_GETREGS");
350: break;
351: #ifdef PT_SETFPREGS
352: case PT_SETFPREGS:
353: (void)printf("PT_SETFPREGS");
354: break;
355: #endif
356: case PT_SETREGS:
357: (void)printf("PT_SETREGS");
358: break;
359: #ifdef PT_STEP
360: case PT_STEP:
361: (void)printf("PT_STEP");
362: break;
363: #endif
364: #ifdef PT_WCOOKIE
365: case PT_WCOOKIE:
366: (void)printf("PT_WCOOKIE");
367: break;
368: #endif
369: default:
370: (void)printf("%ld", (long)*ap);
371: break;
372: }
373: sep = ',';
374: ap++;
375: narg--;
376: }
377:
378: static void
379: pn(void (*f)(int))
380: {
381: if (sep)
382: (void)putchar(sep);
383: if (fancy && f != NULL)
384: f((int)*ap);
385: else if (decimal)
386: (void)printf("%ld", (long)*ap);
387: else
388: (void)printf("%#lx", (long)*ap);
389: ap++;
390: narg--;
391: sep = ',';
392: }
393:
394: #ifdef __LP64__
395: #define plln() pn(NULL)
396: #elif _BYTE_ORDER == _LITTLE_ENDIAN
397: static void
398: plln(void)
399: {
400: long long val = ((long long)*ap) & 0xffffffff;
401: ap++;
402: val |= ((long long)*ap) << 32;
403: ap++;
404: narg -= 2;
405: if (sep)
406: (void)putchar(sep);
407: if (decimal)
408: (void)printf("%lld", val);
409: else
410: (void)printf("%#llx", val);
411: sep = ',';
412: }
413: #else
414: static void
415: plln(void)
416: {
417: long long val = ((long long)*ap) << 32;
418: ap++;
419: val |= ((long long)*ap) & 0xffffffff;
420: ap++;
421: narg -= 2;
422: if (sep)
423: (void)putchar(sep);
424: if (decimal)
425: (void)printf("%lld", val);
426: else
427: (void)printf("%#llx", val);
428: sep = ',';
429: }
430: #endif
1.51 otto 431:
1.12 espie 432: static void
1.17 deraadt 433: ktrsyscall(struct ktr_syscall *ktr)
1.1 deraadt 434: {
1.52 otto 435: narg = ktr->ktr_argsize / sizeof(register_t);
436: sep = '\0';
1.1 deraadt 437:
438: if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0)
439: (void)printf("[%d]", ktr->ktr_code);
440: else
441: (void)printf("%s", current->sysnames[ktr->ktr_code]);
442: ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
1.27 mickey 443: (void)putchar('(');
1.52 otto 444:
1.54 otto 445: if (current != &emulations[0])
446: goto nonnative;
447:
1.52 otto 448: switch (ktr->ktr_code) {
449: case SYS_ioctl: {
450: const char *cp;
451:
452: pn(NULL);
453: if (!fancy)
454: break;
455: if ((cp = ioctlname(*ap)) != NULL)
456: (void)printf(",%s", cp);
457: else
458: ioctldecode(*ap);
459: ap++;
460: narg--;
461: break;
462: }
463: case SYS___sysctl: {
464: int *np, n;
465:
466: if (!fancy)
467: break;
468: n = ap[1];
469: if (n > CTL_MAXNAME)
470: n = CTL_MAXNAME;
471: np = (int *)(ap + 6);
472: for (; n--; np++) {
473: if (sep)
474: putchar(sep);
475: printf("%d", *np);
476: sep = '.';
1.1 deraadt 477: }
1.52 otto 478:
479: sep = ',';
480: ap += 2;
481: narg -= 2;
482: break;
483: }
484: case SYS_ptrace:
485: if (!fancy)
486: break;
487: ptracedecode();
488: break;
489: case SYS_access:
490: pn(NULL);
491: pn(accessmodename);
492: break;
493: case SYS_chmod:
494: case SYS_fchmod:
495: pn( NULL);
496: pn(modename);
497: break;
498: case SYS_fcntl: {
499: int cmd;
500: int arg;
501: pn(NULL);
502: if (!fancy)
503: break;
504: cmd = ap[0];
505: arg = ap[1];
506: (void)putchar(',');
507: fcntlcmdname(cmd, arg);
508: ap += 2;
509: narg -= 2;
510: break;
511: }
512: case SYS_flock:
513: pn(NULL);
514: pn(flockname);
515: break;
516: case SYS_getrlimit:
517: case SYS_setrlimit:
518: pn(rlimitname);
519: break;
520: case SYS_getsockopt:
521: case SYS_setsockopt: {
522: int level;
523:
524: pn(NULL);
525: level = *ap;
526: pn(sockoptlevelname);
527: if (level == SOL_SOCKET)
528: pn(sockoptname);
529: break;
530: }
531: case SYS_kill:
532: pn(NULL);
533: pn(signame);
534: break;
535: case SYS_lseek:
536: pn(NULL);
537: /* skip padding */
538: ap++;
539: narg--;
540: plln();
541: pn(whencename);
542: break;
543: case SYS_madvise:
544: pn(NULL);
545: pn(NULL);
546: pn(madvisebehavname);
547: break;
548: case SYS_minherit:
549: pn(NULL);
550: pn(NULL);
551: pn(minheritname);
552: break;
553: case SYS_mlockall:
554: pn(mlockallname);
555: break;
556: case SYS_mmap:
557: pn(NULL);
558: pn(NULL);
559: pn(mmapprotname);
560: pn(mmapflagsname);
561: pn(NULL);
562: /* skip padding */
563: ap++;
564: narg--;
565: plln();
566: break;
567: case SYS_mprotect:
568: pn(NULL);
569: pn(NULL);
570: pn(mmapprotname);
571: break;
572: case SYS_mquery:
573: pn(NULL);
574: pn(NULL);
575: pn(mmapprotname);
576: pn(mmapflagsname);
577: pn(NULL);
578: /* skip padding */
579: ap++;
580: narg--;
581: plln();
582: break;
583: case SYS_msync:
584: pn(NULL);
585: pn(NULL);
586: pn(msyncflagsname);
587: break;
588: case SYS_msgctl:
589: pn(NULL);
590: pn(shmctlname);
591: break;
592: case SYS_open: {
593: int flags;
594: int mode;
595:
596: pn(NULL);
597: if (!fancy)
598: break;
599: flags = ap[0];
600: mode = ap[1];
601: (void)putchar(',');
602: flagsandmodename(flags, mode);
603: ap += 2;
604: narg -= 2;
605: break;
606: }
607: case SYS_pread:
608: case SYS_preadv:
609: case SYS_pwrite:
610: case SYS_pwritev:
611: pn(NULL);
612: pn(NULL);
613: pn(NULL);
614: /* skip padding */
615: ap++;
616: narg--;
617: plln();
618: break;
619: case SYS_recvmsg:
620: case SYS_sendmsg:
621: pn(NULL);
622: pn(NULL);
623: pn(sendrecvflagsname);
624: break;
625: case SYS_recvfrom:
626: case SYS_sendto:
627: pn(NULL);
628: pn(NULL);
629: pn(NULL);
630: pn(sendrecvflagsname);
631: break;
632: case SYS___semctl:
633: pn(NULL);
634: pn(NULL);
635: pn(semctlname);
636: break;
637: case SYS_semget:
638: pn(NULL);
639: pn(NULL);
640: pn(semgetname);
641: break;
642: case SYS_shmat:
643: pn(NULL);
644: pn(NULL);
645: pn(shmatname);
646: break;
647: case SYS_shmctl:
648: pn(NULL);
649: pn(shmctlname);
650: break;
651: case SYS_sigaction:
652: pn(signame);
653: break;
654: case SYS_sigprocmask:
655: pn(sigprocmaskhowname);
656: break;
657: case SYS_socket: {
658: int sockdomain = *ap;
659:
660: pn(sockdomainname);
661: pn(socktypename);
662: if (sockdomain == PF_INET || sockdomain == PF_INET6)
663: pn(sockipprotoname);
664: break;
665: }
666: case SYS_socketpair:
667: pn(sockdomainname);
668: pn(socktypename);
669: break;
670: case SYS_truncate:
671: case SYS_ftruncate:
672: pn(NULL);
673: /* skip padding */
674: ap++;
675: narg--;
676: plln();
677: break;
678: case SYS_wait4:
679: pn(NULL);
680: pn(NULL);
681: pn(wait4optname);
682: break;
683: }
684:
1.54 otto 685: nonnative:
1.52 otto 686: while (narg) {
687: if (sep)
688: putchar(sep);
689: if (decimal)
690: (void)printf("%ld", (long)*ap);
691: else
692: (void)printf("%#lx", (long)*ap);
693: sep = ',';
694: ap++;
695: narg--;
1.1 deraadt 696: }
1.27 mickey 697: (void)printf(")\n");
1.1 deraadt 698: }
699:
1.12 espie 700: static void
1.17 deraadt 701: ktrsysret(struct ktr_sysret *ktr)
1.1 deraadt 702: {
1.50 deraadt 703: register_t ret = ktr->ktr_retval;
1.12 espie 704: int error = ktr->ktr_error;
705: int code = ktr->ktr_code;
1.1 deraadt 706:
707: if (code >= current->nsysnames || code < 0)
708: (void)printf("[%d] ", code);
709: else
710: (void)printf("%s ", current->sysnames[code]);
711:
712: if (error == 0) {
713: if (fancy) {
1.50 deraadt 714: (void)printf("%ld", (long)ret);
1.1 deraadt 715: if (ret < 0 || ret > 9)
1.50 deraadt 716: (void)printf("/%#lx", (long)ret);
1.1 deraadt 717: } else {
718: if (decimal)
1.50 deraadt 719: (void)printf("%ld", (long)ret);
1.1 deraadt 720: else
1.50 deraadt 721: (void)printf("%#lx", (long)ret);
1.1 deraadt 722: }
723: } else if (error == ERESTART)
724: (void)printf("RESTART");
725: else if (error == EJUSTRETURN)
726: (void)printf("JUSTRETURN");
727: else {
728: (void)printf("-1 errno %d", ktr->ktr_error);
729: if (fancy)
730: (void)printf(" %s", strerror(ktr->ktr_error));
731: }
732: (void)putchar('\n');
733: }
734:
1.12 espie 735: static void
1.37 tedu 736: ktrnamei(const char *cp, size_t len)
1.1 deraadt 737: {
1.37 tedu 738: (void)printf("\"%.*s\"\n", (int)len, cp);
1.1 deraadt 739: }
740:
1.12 espie 741: static void
1.37 tedu 742: ktremul(char *cp, size_t len)
1.1 deraadt 743: {
744: char name[1024];
745:
746: if (len >= sizeof(name))
747: errx(1, "Emulation name too long");
748:
749: strncpy(name, cp, len);
750: name[len] = '\0';
751: (void)printf("\"%s\"\n", name);
752:
753: setemul(name);
754: }
755:
1.12 espie 756: static void
1.37 tedu 757: ktrgenio(struct ktr_genio *ktr, size_t len)
1.1 deraadt 758: {
1.37 tedu 759: unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
760: int i, j;
761: size_t datalen = len - sizeof(struct ktr_genio);
1.12 espie 762: static int screenwidth = 0;
1.31 tedu 763: int col = 0, width, bpl;
1.32 tedu 764: unsigned char visbuf[5], *cp, c;
1.1 deraadt 765:
766: if (screenwidth == 0) {
767: struct winsize ws;
768:
769: if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
770: ws.ws_col > 8)
771: screenwidth = ws.ws_col;
772: else
773: screenwidth = 80;
774: }
1.37 tedu 775: printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1.1 deraadt 776: ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
777: if (maxdata && datalen > maxdata)
778: datalen = maxdata;
1.31 tedu 779: if (iohex && !datalen)
780: return;
781: if (iohex == 1) {
782: putchar('\t');
783: col = 8;
784: for (i = 0; i < datalen; i++) {
1.35 tedu 785: printf("%02x", dp[i]);
1.31 tedu 786: col += 3;
787: if (i < datalen - 1) {
788: if (col + 3 > screenwidth) {
789: printf("\n\t");
790: col = 8;
791: } else
792: putchar(' ');
793: }
794: }
795: putchar('\n');
796: return;
797: }
798: if (iohex == 2) {
799: bpl = (screenwidth - 13)/4;
800: if (bpl <= 0)
801: bpl = 1;
802: for (i = 0; i < datalen; i += bpl) {
803: printf(" %04x: ", i);
804: for (j = 0; j < bpl; j++) {
805: if (i+j >= datalen)
806: printf(" ");
807: else
1.35 tedu 808: printf("%02x ", dp[i+j]);
1.31 tedu 809: }
810: putchar(' ');
811: for (j = 0; j < bpl; j++) {
812: if (i+j >= datalen)
813: break;
814: c = dp[i+j];
815: if (!isprint(c))
816: c = '.';
817: putchar(c);
818: }
819: putchar('\n');
820: }
821: return;
822: }
1.1 deraadt 823: (void)printf(" \"");
824: col = 8;
825: for (; datalen > 0; datalen--, dp++) {
1.31 tedu 826: (void)vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
1.1 deraadt 827: cp = visbuf;
1.17 deraadt 828:
1.1 deraadt 829: /*
830: * Keep track of printables and
831: * space chars (like fold(1)).
832: */
833: if (col == 0) {
834: (void)putchar('\t');
835: col = 8;
836: }
1.17 deraadt 837: switch (*cp) {
1.1 deraadt 838: case '\n':
839: col = 0;
840: (void)putchar('\n');
841: continue;
842: case '\t':
843: width = 8 - (col&07);
844: break;
845: default:
846: width = strlen(cp);
847: }
848: if (col + width > (screenwidth-2)) {
849: (void)printf("\\\n\t");
850: col = 8;
851: }
852: col += width;
853: do {
854: (void)putchar(*cp++);
855: } while (*cp);
856: }
857: if (col == 0)
858: (void)printf(" ");
859: (void)printf("\"\n");
860: }
861:
1.12 espie 862: static void
1.17 deraadt 863: ktrpsig(struct ktr_psig *psig)
1.1 deraadt 864: {
865: (void)printf("SIG%s ", sys_signame[psig->signo]);
866: if (psig->action == SIG_DFL)
1.14 deraadt 867: (void)printf("SIG_DFL code %d", psig->code);
1.1 deraadt 868: else
1.14 deraadt 869: (void)printf("caught handler=0x%lx mask=0x%x",
870: (u_long)psig->action, psig->mask);
871: switch (psig->signo) {
872: case SIGSEGV:
873: case SIGILL:
874: case SIGBUS:
875: case SIGFPE:
876: printf(" addr=%p trapno=%d", psig->si.si_addr,
877: psig->si.si_trapno);
878: break;
879: default:
880: break;
881: }
882: printf("\n");
1.1 deraadt 883: }
884:
1.12 espie 885: static void
1.17 deraadt 886: ktrcsw(struct ktr_csw *cs)
1.1 deraadt 887: {
888: (void)printf("%s %s\n", cs->out ? "stop" : "resume",
889: cs->user ? "user" : "kernel");
890: }
891:
1.55 otto 892:
893:
894: void
895: ktrsockaddr(struct sockaddr *sa)
896: {
897: /*
898: TODO: Support additional address families
899: #include <netnatm/natm.h>
900: struct sockaddr_natm *natm;
901: #include <netsmb/netbios.h>
902: struct sockaddr_nb *nb;
903: */
904: char addr[64];
905:
906: /*
907: * note: ktrstruct() has already verified that sa points to a
908: * buffer at least sizeof(struct sockaddr) bytes long and exactly
909: * sa->sa_len bytes long.
910: */
911: printf("struct sockaddr { ");
912: sockfamilyname(sa->sa_family);
913: printf(", ");
914:
915: #define check_sockaddr_len(n) \
916: if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \
917: printf("invalid"); \
918: break; \
919: }
920:
921: switch(sa->sa_family) {
922: case AF_INET: {
923: struct sockaddr_in *sa_in;
924:
925: sa_in = (struct sockaddr_in *)sa;
926: check_sockaddr_len(in);
927: inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);
928: printf("%s:%u", addr, ntohs(sa_in->sin_port));
929: break;
930: }
931: case AF_INET6: {
932: struct sockaddr_in6 *sa_in6;
933:
934: sa_in6 = (struct sockaddr_in6 *)sa;
935: check_sockaddr_len(in6);
936: inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);
937: printf("[%s]:%u", addr, htons(sa_in6->sin6_port));
938: break;
939: }
940: #ifdef IPX
941: case AF_IPX: {
942: struct sockaddr_ipx *sa_ipx;
943:
944: sa_ipx = (struct sockaddr_ipx *)sa;
945: check_sockaddr_len(ipx);
946: /* XXX wish we had ipx_ntop */
947: printf("%s", ipx_ntoa(sa_ipx->sipx_addr));
948: break;
949: }
950: #endif
951: case AF_UNIX: {
952: struct sockaddr_un *sa_un;
953:
954: sa_un = (struct sockaddr_un *)sa;
955: if (sa_un->sun_len <= sizeof(sa_un->sun_len) +
956: sizeof(sa_un->sun_family)) {
957: printf("invalid");
958: break;
959: }
960: printf("\"%.*s\"", (int)(sa_un->sun_len -
961: sizeof(sa_un->sun_len) - sizeof(sa_un->sun_family)),
962: sa_un->sun_path);
963: break;
964: }
965: default:
966: printf("unknown address family");
967: }
968: printf(" }\n");
969: }
970:
971: void
972: ktrstat(struct stat *statp)
973: {
974: char mode[12], timestr[PATH_MAX + 4];
975: struct passwd *pwd;
976: struct group *grp;
977: struct tm *tm;
978:
979: /*
980: * note: ktrstruct() has already verified that statp points to a
981: * buffer exactly sizeof(struct stat) bytes long.
982: */
983: printf("struct stat {");
984: strmode(statp->st_mode, mode);
985: printf("dev=%d, ino=%u, mode=%s, nlink=%u, ",
986: statp->st_dev, statp->st_ino, mode, statp->st_nlink);
987: if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
988: printf("uid=%u, ", statp->st_uid);
989: else
990: printf("uid=\"%s\", ", pwd->pw_name);
991: if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
992: printf("gid=%u, ", statp->st_gid);
993: else
994: printf("gid=\"%s\", ", grp->gr_name);
995: printf("rdev=%d, ", statp->st_rdev);
996: printf("atime=");
997: if (resolv == 0)
998: printf("%jd", (intmax_t)statp->st_atim.tv_sec);
999: else {
1000: tm = localtime(&statp->st_atim.tv_sec);
1001: (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1002: printf("\"%s\"", timestr);
1003: }
1004: if (statp->st_atim.tv_nsec != 0)
1005: printf(".%09ld, ", statp->st_atim.tv_nsec);
1006: else
1007: printf(", ");
1008: printf("stime=");
1009: if (resolv == 0)
1010: printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1011: else {
1012: tm = localtime(&statp->st_mtim.tv_sec);
1013: (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1014: printf("\"%s\"", timestr);
1015: }
1016: if (statp->st_mtim.tv_nsec != 0)
1017: printf(".%09ld, ", statp->st_mtim.tv_nsec);
1018: else
1019: printf(", ");
1020: printf("ctime=");
1021: if (resolv == 0)
1022: printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1023: else {
1024: tm = localtime(&statp->st_ctim.tv_sec);
1025: (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1026: printf("\"%s\"", timestr);
1027: }
1028: if (statp->st_ctim.tv_nsec != 0)
1029: printf(".%09ld, ", statp->st_ctim.tv_nsec);
1030: else
1031: printf(", ");
1032: printf("size=%lld, blocks=%lld, blksize=%u, flags=0x%x, gen=0x%x",
1033: statp->st_size, statp->st_blocks, statp->st_blksize,
1034: statp->st_flags, statp->st_gen);
1035: printf(" }\n");
1036: }
1037:
1038: void
1039: ktrstruct(char *buf, size_t buflen)
1040: {
1041: char *name, *data;
1042: size_t namelen, datalen;
1043: int i;
1044: struct stat sb;
1045: struct sockaddr_storage ss;
1046:
1047: for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0';
1048: ++namelen)
1049: /* nothing */;
1050: if (namelen == buflen)
1051: goto invalid;
1052: if (name[namelen] != '\0')
1053: goto invalid;
1054: data = buf + namelen + 1;
1055: datalen = buflen - namelen - 1;
1056: if (datalen == 0)
1057: goto invalid;
1058: /* sanity check */
1059: for (i = 0; i < namelen; ++i)
1060: if (!isalpha((unsigned char)name[i]))
1061: goto invalid;
1062: if (strcmp(name, "stat") == 0) {
1063: if (datalen != sizeof(struct stat))
1064: goto invalid;
1065: memcpy(&sb, data, datalen);
1066: ktrstat(&sb);
1067: } else if (strcmp(name, "sockaddr") == 0) {
1068: if (datalen > sizeof(ss))
1069: goto invalid;
1070: memcpy(&ss, data, datalen);
1071: if ((ss.ss_family != AF_UNIX &&
1072: datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len)
1073: goto invalid;
1074: ktrsockaddr((struct sockaddr *)&ss);
1075: } else {
1076: printf("unknown structure\n");
1077: }
1078: return;
1079: invalid:
1080: printf("invalid record\n");
1081: }
1082:
1.12 espie 1083: static void
1.17 deraadt 1084: usage(void)
1.1 deraadt 1085: {
1086:
1.19 mickey 1087: extern char *__progname;
1088: fprintf(stderr, "usage: %s "
1.55 otto 1089: "[-dlnRrTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n"
1.40 sobrado 1090: "%*s[-t [ceinsw]]\n",
1.51 otto 1091: __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
1.1 deraadt 1092: exit(1);
1093: }
1094:
1.12 espie 1095: static void
1.17 deraadt 1096: setemul(const char *name)
1.1 deraadt 1097: {
1098: int i;
1.17 deraadt 1099:
1.1 deraadt 1100: for (i = 0; emulations[i].name != NULL; i++)
1101: if (strcmp(emulations[i].name, name) == 0) {
1102: current = &emulations[i];
1103: return;
1104: }
1105: warnx("Emulation `%s' unknown", name);
1106: }