]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - usr.bin/kdump/kdump.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / usr.bin / kdump / kdump.c
1 /*-
2  * Copyright (c) 1988, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #ifndef lint
31 static const char copyright[] =
32 "@(#) Copyright (c) 1988, 1993\n\
33         The Regents of the University of California.  All rights reserved.\n";
34 #endif /* not lint */
35
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)kdump.c     8.1 (Berkeley) 6/6/93";
39 #endif
40 #endif /* not lint */
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #define _KERNEL
45 extern int errno;
46 #include <sys/errno.h>
47 #undef _KERNEL
48 #include <sys/param.h>
49 #include <sys/errno.h>
50 #define _KERNEL
51 #include <sys/time.h>
52 #undef _KERNEL
53 #include <sys/uio.h>
54 #include <sys/ktrace.h>
55 #include <sys/ioctl.h>
56 #include <sys/socket.h>
57 #include <sys/stat.h>
58 #include <sys/sysent.h>
59 #include <sys/un.h>
60 #include <sys/queue.h>
61 #ifdef IPX
62 #include <sys/types.h>
63 #include <netipx/ipx.h>
64 #endif
65 #ifdef NETATALK
66 #include <netatalk/at.h>
67 #endif
68 #include <arpa/inet.h>
69 #include <netinet/in.h>
70 #include <ctype.h>
71 #include <dlfcn.h>
72 #include <err.h>
73 #include <grp.h>
74 #include <inttypes.h>
75 #include <locale.h>
76 #include <pwd.h>
77 #include <stdio.h>
78 #include <stdlib.h>
79 #include <string.h>
80 #include <time.h>
81 #include <unistd.h>
82 #include <vis.h>
83 #include "ktrace.h"
84 #include "kdump_subr.h"
85
86 u_int abidump(struct ktr_header *);
87 int fetchprocinfo(struct ktr_header *, u_int *);
88 int fread_tail(void *, int, int);
89 void dumpheader(struct ktr_header *);
90 void ktrsyscall(struct ktr_syscall *, u_int);
91 void ktrsysret(struct ktr_sysret *, u_int);
92 void ktrnamei(char *, int);
93 void hexdump(char *, int, int);
94 void visdump(char *, int, int);
95 void ktrgenio(struct ktr_genio *, int);
96 void ktrpsig(struct ktr_psig *);
97 void ktrcsw(struct ktr_csw *);
98 void ktruser(int, unsigned char *);
99 void ktrsockaddr(struct sockaddr *);
100 void ktrstat(struct stat *);
101 void ktrstruct(char *, size_t);
102 void usage(void);
103 void sockfamilyname(int);
104 const char *ioctlname(u_long);
105
106 int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
107     resolv = 0, abiflag = 0;
108 const char *tracefile = DEF_TRACEFILE;
109 struct ktr_header ktr_header;
110
111 #define TIME_FORMAT     "%b %e %T %Y"
112 #define eqs(s1, s2)     (strcmp((s1), (s2)) == 0)
113
114 #define print_number(i,n,c) do {                \
115         if (decimal)                            \
116                 printf("%c%ld", c, (long)*i);   \
117         else                                    \
118                 printf("%c%#lx", c, (long)*i);  \
119         i++;                                    \
120         n--;                                    \
121         c = ',';                                \
122         } while (0);
123
124 #if defined(__amd64__) || defined(__i386__)
125
126 void linux_ktrsyscall(struct ktr_syscall *);
127 void linux_ktrsysret(struct ktr_sysret *);
128 extern char *linux_syscallnames[];
129 extern int nlinux_syscalls;
130
131 /*
132  * from linux.h
133  * Linux syscalls return negative errno's, we do positive and map them
134  */
135 static int bsd_to_linux_errno[ELAST + 1] = {
136         -0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
137         -10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
138         -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
139         -30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
140         -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
141         -100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
142         -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
143         -116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
144         -6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
145         -72, -67, -71
146 };
147 #endif
148
149 struct proc_info
150 {
151         TAILQ_ENTRY(proc_info)  info;
152         u_int                   sv_flags;
153         pid_t                   pid;
154 };
155
156 TAILQ_HEAD(trace_procs, proc_info) trace_procs;
157
158 int
159 main(int argc, char *argv[])
160 {
161         int ch, ktrlen, size;
162         void *m;
163         int trpoints = ALL_POINTS;
164         int drop_logged;
165         pid_t pid = 0;
166         u_int sv_flags;
167
168         (void) setlocale(LC_CTYPE, "");
169
170         while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
171                 switch((char)ch) {
172                 case 'A':
173                         abiflag = 1;
174                         break;
175                 case 'f':
176                         tracefile = optarg;
177                         break;
178                 case 'd':
179                         decimal = 1;
180                         break;
181                 case 'l':
182                         tail = 1;
183                         break;
184                 case 'm':
185                         maxdata = atoi(optarg);
186                         break;
187                 case 'n':
188                         fancy = 0;
189                         break;
190                 case 'p':
191                         pid = atoi(optarg);
192                         break;
193                 case 'r':
194                         resolv = 1;
195                         break;
196                 case 's':
197                         suppressdata = 1;
198                         break;
199                 case 'E':
200                         timestamp = 3;  /* elapsed timestamp */
201                         break;
202                 case 'H':
203                         threads = 1;
204                         break;
205                 case 'R':
206                         timestamp = 2;  /* relative timestamp */
207                         break;
208                 case 'T':
209                         timestamp = 1;
210                         break;
211                 case 't':
212                         trpoints = getpoints(optarg);
213                         if (trpoints < 0)
214                                 errx(1, "unknown trace point in %s", optarg);
215                         break;
216                 default:
217                         usage();
218                 }
219
220         if (argc > optind)
221                 usage();
222
223         m = (void *)malloc(size = 1025);
224         if (m == NULL)
225                 errx(1, "%s", strerror(ENOMEM));
226         if (!freopen(tracefile, "r", stdin))
227                 err(1, "%s", tracefile);
228         TAILQ_INIT(&trace_procs);
229         drop_logged = 0;
230         while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
231                 if (ktr_header.ktr_type & KTR_DROP) {
232                         ktr_header.ktr_type &= ~KTR_DROP;
233                         if (!drop_logged && threads) {
234                                 (void)printf(
235                                     "%6jd %6jd %-8.*s Events dropped.\n",
236                                     (intmax_t)ktr_header.ktr_pid,
237                                     ktr_header.ktr_tid > 0 ?
238                                     (intmax_t)ktr_header.ktr_tid : 0,
239                                     MAXCOMLEN, ktr_header.ktr_comm);
240                                 drop_logged = 1;
241                         } else if (!drop_logged) {
242                                 (void)printf("%6jd %-8.*s Events dropped.\n",
243                                     (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
244                                     ktr_header.ktr_comm);
245                                 drop_logged = 1;
246                         }
247                 }
248                 if (trpoints & (1<<ktr_header.ktr_type))
249                         if (pid == 0 || ktr_header.ktr_pid == pid)
250                                 dumpheader(&ktr_header);
251                 if ((ktrlen = ktr_header.ktr_len) < 0)
252                         errx(1, "bogus length 0x%x", ktrlen);
253                 if (ktrlen > size) {
254                         m = (void *)realloc(m, ktrlen+1);
255                         if (m == NULL)
256                                 errx(1, "%s", strerror(ENOMEM));
257                         size = ktrlen;
258                 }
259                 if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
260                         errx(1, "data too short");
261                 if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
262                         continue;
263                 sv_flags = abidump(&ktr_header);
264                 if (pid && ktr_header.ktr_pid != pid)
265                         continue;
266                 if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
267                         continue;
268                 drop_logged = 0;
269                 switch (ktr_header.ktr_type) {
270                 case KTR_SYSCALL:
271 #if defined(__amd64__) || defined(__i386__)
272                         if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
273                                 linux_ktrsyscall((struct ktr_syscall *)m);
274                         else
275 #endif
276                                 ktrsyscall((struct ktr_syscall *)m, sv_flags);
277                         break;
278                 case KTR_SYSRET:
279 #if defined(__amd64__) || defined(__i386__)
280                         if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
281                                 linux_ktrsysret((struct ktr_sysret *)m);
282                         else
283 #endif
284                                 ktrsysret((struct ktr_sysret *)m, sv_flags);
285                         break;
286                 case KTR_NAMEI:
287                 case KTR_SYSCTL:
288                         ktrnamei(m, ktrlen);
289                         break;
290                 case KTR_GENIO:
291                         ktrgenio((struct ktr_genio *)m, ktrlen);
292                         break;
293                 case KTR_PSIG:
294                         ktrpsig((struct ktr_psig *)m);
295                         break;
296                 case KTR_CSW:
297                         ktrcsw((struct ktr_csw *)m);
298                         break;
299                 case KTR_USER:
300                         ktruser(ktrlen, m);
301                         break;
302                 case KTR_STRUCT:
303                         ktrstruct(m, ktrlen);
304                         break;
305                 default:
306                         printf("\n");
307                         break;
308                 }
309                 if (tail)
310                         (void)fflush(stdout);
311         }
312         return 0;
313 }
314
315 int
316 fread_tail(void *buf, int size, int num)
317 {
318         int i;
319
320         while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
321                 (void)sleep(1);
322                 clearerr(stdin);
323         }
324         return (i);
325 }
326
327 int
328 fetchprocinfo(struct ktr_header *kth, u_int *flags)
329 {
330         struct proc_info *pi;
331
332         switch (kth->ktr_type) {
333         case KTR_PROCCTOR:
334                 TAILQ_FOREACH(pi, &trace_procs, info) {
335                         if (pi->pid == kth->ktr_pid) {
336                                 TAILQ_REMOVE(&trace_procs, pi, info);
337                                 break;
338                         }
339                 }
340                 pi = malloc(sizeof(struct proc_info));
341                 if (pi == NULL)
342                         errx(1, "%s", strerror(ENOMEM));
343                 pi->sv_flags = *flags;
344                 pi->pid = kth->ktr_pid;
345                 TAILQ_INSERT_TAIL(&trace_procs, pi, info);
346                 return (1);
347
348         case KTR_PROCDTOR:
349                 TAILQ_FOREACH(pi, &trace_procs, info) {
350                         if (pi->pid == kth->ktr_pid) {
351                                 TAILQ_REMOVE(&trace_procs, pi, info);
352                                 free(pi);
353                                 break;
354                         }
355                 }
356                 return (1);
357         }
358
359         return (0);
360 }
361
362 u_int
363 abidump(struct ktr_header *kth)
364 {
365         struct proc_info *pi;
366         const char *abi;
367         const char *arch;
368         u_int flags = 0;
369
370         TAILQ_FOREACH(pi, &trace_procs, info) {
371                 if (pi->pid == kth->ktr_pid) {
372                         flags = pi->sv_flags;
373                         break;
374                 }
375         }
376
377         if (abiflag == 0)
378                 return (flags);
379
380         switch (flags & SV_ABI_MASK) {
381         case SV_ABI_LINUX:
382                 abi = "L";
383                 break;
384         case SV_ABI_FREEBSD:
385                 abi = "F";
386                 break;
387         default:
388                 abi = "U";
389                 break;
390         }
391
392         if (flags != 0) {
393                 if (flags & SV_LP64)
394                         arch = "64";
395                 else
396                         arch = "32";
397         } else
398                 arch = "00";
399
400         printf("%s%s  ", abi, arch);
401
402         return (flags);
403 }
404
405 void
406 dumpheader(struct ktr_header *kth)
407 {
408         static char unknown[64];
409         static struct timeval prevtime, temp;
410         const char *type;
411
412         switch (kth->ktr_type) {
413         case KTR_SYSCALL:
414                 type = "CALL";
415                 break;
416         case KTR_SYSRET:
417                 type = "RET ";
418                 break;
419         case KTR_NAMEI:
420                 type = "NAMI";
421                 break;
422         case KTR_GENIO:
423                 type = "GIO ";
424                 break;
425         case KTR_PSIG:
426                 type = "PSIG";
427                 break;
428         case KTR_CSW:
429                 type = "CSW ";
430                 break;
431         case KTR_USER:
432                 type = "USER";
433                 break;
434         case KTR_STRUCT:
435                 type = "STRU";
436                 break;
437         case KTR_SYSCTL:
438                 type = "SCTL";
439                 break;
440         case KTR_PROCCTOR:
441                 /* FALLTHROUGH */
442         case KTR_PROCDTOR:
443                 return;
444         default:
445                 (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
446                 type = unknown;
447         }
448
449         /*
450          * The ktr_tid field was previously the ktr_buffer field, which held
451          * the kernel pointer value for the buffer associated with data
452          * following the record header.  It now holds a threadid, but only
453          * for trace files after the change.  Older trace files still contain
454          * kernel pointers.  Detect this and suppress the results by printing
455          * negative tid's as 0.
456          */
457         if (threads)
458                 (void)printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
459                     kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
460                     MAXCOMLEN, kth->ktr_comm);
461         else
462                 (void)printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
463                     kth->ktr_comm);
464         if (timestamp) {
465                 if (timestamp == 3) {
466                         if (prevtime.tv_sec == 0)
467                                 prevtime = kth->ktr_time;
468                         timevalsub(&kth->ktr_time, &prevtime);
469                 }
470                 if (timestamp == 2) {
471                         temp = kth->ktr_time;
472                         timevalsub(&kth->ktr_time, &prevtime);
473                         prevtime = temp;
474                 }
475                 (void)printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
476                     kth->ktr_time.tv_usec);
477         }
478         (void)printf("%s  ", type);
479 }
480
481 #include <sys/syscall.h>
482 #define KTRACE
483 #include <sys/kern/syscalls.c>
484 #undef KTRACE
485 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
486
487 void
488 ktrsyscall(struct ktr_syscall *ktr, u_int flags)
489 {
490         int narg = ktr->ktr_narg;
491         register_t *ip;
492
493         if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
494             (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
495                 (void)printf("[%d]", ktr->ktr_code);
496         else
497                 (void)printf("%s", syscallnames[ktr->ktr_code]);
498         ip = &ktr->ktr_args[0];
499         if (narg) {
500                 char c = '(';
501                 if (fancy &&
502                     (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
503                         if (ktr->ktr_code == SYS_ioctl) {
504                                 const char *cp;
505                                 print_number(ip,narg,c);
506                                 if ((cp = ioctlname(*ip)) != NULL)
507                                         (void)printf(",%s", cp);
508                                 else {
509                                         if (decimal)
510                                                 (void)printf(",%ld", (long)*ip);
511                                         else
512                                                 (void)printf(",%#lx ", (long)*ip);
513                                 }
514                                 c = ',';
515                                 ip++;
516                                 narg--;
517                         } else if (ktr->ktr_code == SYS_ptrace) {
518                                 (void)putchar('(');
519                                 ptraceopname ((int)*ip);
520                                 c = ',';
521                                 ip++;
522                                 narg--;
523                         } else if (ktr->ktr_code == SYS_access ||
524                                    ktr->ktr_code == SYS_eaccess) {
525                                 print_number(ip,narg,c);
526                                 (void)putchar(',');
527                                 accessmodename ((int)*ip);
528                                 ip++;
529                                 narg--;
530                         } else if (ktr->ktr_code == SYS_open) {
531                                 int     flags;
532                                 int     mode;
533                                 print_number(ip,narg,c);
534                                 flags = *ip;
535                                 mode = *++ip;
536                                 (void)putchar(',');
537                                 flagsandmodename (flags, mode, decimal);
538                                 ip++;
539                                 narg-=2;
540                         } else if (ktr->ktr_code == SYS_wait4) {
541                                 print_number(ip,narg,c);
542                                 print_number(ip,narg,c);
543                                 (void)putchar(',');
544                                 wait4optname ((int)*ip);
545                                 ip++;
546                                 narg--;
547                         } else if (ktr->ktr_code == SYS_chmod ||
548                                    ktr->ktr_code == SYS_fchmod ||
549                                    ktr->ktr_code == SYS_lchmod) {
550                                 print_number(ip,narg,c);
551                                 (void)putchar(',');
552                                 modename ((int)*ip);
553                                 ip++;
554                                 narg--;
555                         } else if (ktr->ktr_code == SYS_mknod) {
556                                 print_number(ip,narg,c);
557                                 (void)putchar(',');
558                                 modename ((int)*ip);
559                                 ip++;
560                                 narg--;
561                         } else if (ktr->ktr_code == SYS_getfsstat) {
562                                 print_number(ip,narg,c);
563                                 print_number(ip,narg,c);
564                                 (void)putchar(',');
565                                 getfsstatflagsname ((int)*ip);
566                                 ip++;
567                                 narg--;
568                         } else if (ktr->ktr_code == SYS_mount) {
569                                 print_number(ip,narg,c);
570                                 print_number(ip,narg,c);
571                                 (void)putchar(',');
572                                 mountflagsname ((int)*ip);
573                                 ip++;
574                                 narg--;
575                         } else if (ktr->ktr_code == SYS_unmount) {
576                                 print_number(ip,narg,c);
577                                 (void)putchar(',');
578                                 mountflagsname ((int)*ip);
579                                 ip++;
580                                 narg--;
581                         } else if (ktr->ktr_code == SYS_recvmsg ||
582                                    ktr->ktr_code == SYS_sendmsg) {
583                                 print_number(ip,narg,c);
584                                 print_number(ip,narg,c);
585                                 (void)putchar(',');
586                                 sendrecvflagsname ((int)*ip);
587                                 ip++;
588                                 narg--;
589                         } else if (ktr->ktr_code == SYS_recvfrom ||
590                                    ktr->ktr_code == SYS_sendto) {
591                                 print_number(ip,narg,c);
592                                 print_number(ip,narg,c);
593                                 print_number(ip,narg,c);
594                                 (void)putchar(',');
595                                 sendrecvflagsname ((int)*ip);
596                                 ip++;
597                                 narg--;
598                         } else if (ktr->ktr_code == SYS_chflags ||
599                                    ktr->ktr_code == SYS_fchflags ||
600                                    ktr->ktr_code == SYS_lchflags) {
601                                 print_number(ip,narg,c);
602                                 (void)putchar(',');
603                                 modename((int)*ip);
604                                 ip++;
605                                 narg--;
606                         } else if (ktr->ktr_code == SYS_kill) {
607                                 print_number(ip,narg,c);
608                                 (void)putchar(',');
609                                 signame((int)*ip);
610                                 ip++;
611                                 narg--;
612                         } else if (ktr->ktr_code == SYS_reboot) {
613                                 (void)putchar('(');
614                                 rebootoptname((int)*ip);
615                                 ip++;
616                                 narg--;
617                         } else if (ktr->ktr_code == SYS_umask) {
618                                 (void)putchar('(');
619                                 modename((int)*ip);
620                                 ip++;
621                                 narg--;
622                         } else if (ktr->ktr_code == SYS_msync) {
623                                 print_number(ip,narg,c);
624                                 print_number(ip,narg,c);
625                                 (void)putchar(',');
626                                 msyncflagsname((int)*ip);
627                                 ip++;
628                                 narg--;
629 #ifdef SYS_freebsd6_mmap
630                         } else if (ktr->ktr_code == SYS_freebsd6_mmap) {
631                                 print_number(ip,narg,c);
632                                 print_number(ip,narg,c);
633                                 (void)putchar(',');
634                                 mmapprotname ((int)*ip);
635                                 (void)putchar(',');
636                                 ip++;
637                                 narg--;
638                                 mmapflagsname ((int)*ip);
639                                 ip++;
640                                 narg--;
641 #endif
642                         } else if (ktr->ktr_code == SYS_mmap) {
643                                 print_number(ip,narg,c);
644                                 print_number(ip,narg,c);
645                                 (void)putchar(',');
646                                 mmapprotname ((int)*ip);
647                                 (void)putchar(',');
648                                 ip++;
649                                 narg--;
650                                 mmapflagsname ((int)*ip);
651                                 ip++;
652                                 narg--;
653                         } else if (ktr->ktr_code == SYS_mprotect) {
654                                 print_number(ip,narg,c);
655                                 print_number(ip,narg,c);
656                                 (void)putchar(',');
657                                 mmapprotname ((int)*ip);
658                                 ip++;
659                                 narg--;
660                         } else if (ktr->ktr_code == SYS_madvise) {
661                                 print_number(ip,narg,c);
662                                 print_number(ip,narg,c);
663                                 (void)putchar(',');
664                                 madvisebehavname((int)*ip);
665                                 ip++;
666                                 narg--;
667                         } else if (ktr->ktr_code == SYS_setpriority) {
668                                 print_number(ip,narg,c);
669                                 print_number(ip,narg,c);
670                                 (void)putchar(',');
671                                 prioname((int)*ip);
672                                 ip++;
673                                 narg--;
674                         } else if (ktr->ktr_code == SYS_fcntl) {
675                                 int cmd;
676                                 int arg;
677                                 print_number(ip,narg,c);
678                                 cmd = *ip;
679                                 arg = *++ip;
680                                 (void)putchar(',');
681                                 fcntlcmdname(cmd, arg, decimal);
682                                 ip++;
683                                 narg-=2;
684                         } else if (ktr->ktr_code == SYS_socket) {
685                                 int sockdomain;
686                                 (void)putchar('(');
687                                 sockdomain=(int)*ip;
688                                 sockdomainname(sockdomain);
689                                 ip++;
690                                 narg--;
691                                 (void)putchar(',');
692                                 socktypename((int)*ip);
693                                 ip++;
694                                 narg--;
695                                 if (sockdomain == PF_INET ||
696                                     sockdomain == PF_INET6) {
697                                         (void)putchar(',');
698                                         sockipprotoname((int)*ip);
699                                         ip++;
700                                         narg--;
701                                 }
702                                 c = ',';
703                         } else if (ktr->ktr_code == SYS_setsockopt ||
704                                    ktr->ktr_code == SYS_getsockopt) {
705                                 print_number(ip,narg,c);
706                                 (void)putchar(',');
707                                 sockoptlevelname((int)*ip, decimal);
708                                 if ((int)*ip == SOL_SOCKET) {
709                                         ip++;
710                                         narg--;
711                                         (void)putchar(',');
712                                         sockoptname((int)*ip);
713                                 }
714                                 ip++;
715                                 narg--;
716 #ifdef SYS_freebsd6_lseek
717                         } else if (ktr->ktr_code == SYS_freebsd6_lseek) {
718                                 print_number(ip,narg,c);
719                                 /* Hidden 'pad' argument, not in lseek(2) */
720                                 print_number(ip,narg,c);
721                                 print_number(ip,narg,c);
722                                 (void)putchar(',');
723                                 whencename ((int)*ip);
724                                 ip++;
725                                 narg--;
726 #endif
727                         } else if (ktr->ktr_code == SYS_lseek) {
728                                 print_number(ip,narg,c);
729                                 /* Hidden 'pad' argument, not in lseek(2) */
730                                 print_number(ip,narg,c);
731                                 (void)putchar(',');
732                                 whencename ((int)*ip);
733                                 ip++;
734                                 narg--;
735
736                         } else if (ktr->ktr_code == SYS_flock) {
737                                 print_number(ip,narg,c);
738                                 (void)putchar(',');
739                                 flockname((int)*ip);
740                                 ip++;
741                                 narg--;
742                         } else if (ktr->ktr_code == SYS_mkfifo ||
743                                    ktr->ktr_code == SYS_mkdir) {
744                                 print_number(ip,narg,c);
745                                 (void)putchar(',');
746                                 modename((int)*ip);
747                                 ip++;
748                                 narg--;
749                         } else if (ktr->ktr_code == SYS_shutdown) {
750                                 print_number(ip,narg,c);
751                                 (void)putchar(',');
752                                 shutdownhowname((int)*ip);
753                                 ip++;
754                                 narg--;
755                         } else if (ktr->ktr_code == SYS_socketpair) {
756                                 (void)putchar('(');
757                                 sockdomainname((int)*ip);
758                                 ip++;
759                                 narg--;
760                                 (void)putchar(',');
761                                 socktypename((int)*ip);
762                                 ip++;
763                                 narg--;
764                                 c = ',';
765                         } else if (ktr->ktr_code == SYS_getrlimit ||
766                                    ktr->ktr_code == SYS_setrlimit) {
767                                 (void)putchar('(');
768                                 rlimitname((int)*ip);
769                                 ip++;
770                                 narg--;
771                                 c = ',';
772                         } else if (ktr->ktr_code == SYS_quotactl) {
773                                 print_number(ip,narg,c);
774                                 (void)putchar(',');
775                                 quotactlname((int)*ip);
776                                 ip++;
777                                 narg--;
778                                 c = ',';
779                         } else if (ktr->ktr_code == SYS_nfssvc) {
780                                 (void)putchar('(');
781                                 nfssvcname((int)*ip);
782                                 ip++;
783                                 narg--;
784                                 c = ',';
785                         } else if (ktr->ktr_code == SYS_rtprio) {
786                                 (void)putchar('(');
787                                 rtprioname((int)*ip);
788                                 ip++;
789                                 narg--;
790                                 c = ',';
791                         } else if (ktr->ktr_code == SYS___semctl) {
792                                 print_number(ip,narg,c);
793                                 print_number(ip,narg,c);
794                                 (void)putchar(',');
795                                 semctlname((int)*ip);
796                                 ip++;
797                                 narg--;
798                         } else if (ktr->ktr_code == SYS_semget) {
799                                 print_number(ip,narg,c);
800                                 print_number(ip,narg,c);
801                                 (void)putchar(',');
802                                 semgetname((int)*ip);
803                                 ip++;
804                                 narg--;
805                         } else if (ktr->ktr_code == SYS_msgctl) {
806                                 print_number(ip,narg,c);
807                                 (void)putchar(',');
808                                 shmctlname((int)*ip);
809                                 ip++;
810                                 narg--;
811                         } else if (ktr->ktr_code == SYS_shmat) {
812                                 print_number(ip,narg,c);
813                                 print_number(ip,narg,c);
814                                 (void)putchar(',');
815                                 shmatname((int)*ip);
816                                 ip++;
817                                 narg--;
818                         } else if (ktr->ktr_code == SYS_shmctl) {
819                                 print_number(ip,narg,c);
820                                 (void)putchar(',');
821                                 shmctlname((int)*ip);
822                                 ip++;
823                                 narg--;
824                         } else if (ktr->ktr_code == SYS_minherit) {
825                                 print_number(ip,narg,c);
826                                 print_number(ip,narg,c);
827                                 (void)putchar(',');
828                                 minheritname((int)*ip);
829                                 ip++;
830                                 narg--;
831                         } else if (ktr->ktr_code == SYS_rfork) {
832                                 (void)putchar('(');
833                                 rforkname((int)*ip);
834                                 ip++;
835                                 narg--;
836                                 c = ',';
837                         } else if (ktr->ktr_code == SYS_lio_listio) {
838                                 (void)putchar('(');
839                                 lio_listioname((int)*ip);
840                                 ip++;
841                                 narg--;
842                                 c = ',';
843                         } else if (ktr->ktr_code == SYS_mlockall) {
844                                 (void)putchar('(');
845                                 mlockallname((int)*ip);
846                                 ip++;
847                                 narg--;
848                         } else if (ktr->ktr_code == SYS_sched_setscheduler) {
849                                 print_number(ip,narg,c);
850                                 (void)putchar(',');
851                                 schedpolicyname((int)*ip);
852                                 ip++;
853                                 narg--;
854                         } else if (ktr->ktr_code == SYS_sched_get_priority_max ||
855                                    ktr->ktr_code == SYS_sched_get_priority_min) {
856                                 (void)putchar('(');
857                                 schedpolicyname((int)*ip);
858                                 ip++;
859                                 narg--;
860                         } else if (ktr->ktr_code == SYS_sendfile) {
861                                 print_number(ip,narg,c);
862                                 print_number(ip,narg,c);
863                                 print_number(ip,narg,c);
864                                 print_number(ip,narg,c);
865                                 print_number(ip,narg,c);
866                                 print_number(ip,narg,c);
867                                 (void)putchar(',');
868                                 sendfileflagsname((int)*ip);
869                                 ip++;
870                                 narg--;
871                         } else if (ktr->ktr_code == SYS_kldsym) {
872                                 print_number(ip,narg,c);
873                                 (void)putchar(',');
874                                 kldsymcmdname((int)*ip);
875                                 ip++;
876                                 narg--;
877                         } else if (ktr->ktr_code == SYS_sigprocmask) {
878                                 (void)putchar('(');
879                                 sigprocmaskhowname((int)*ip);
880                                 ip++;
881                                 narg--;
882                                 c = ',';
883                         } else if (ktr->ktr_code == SYS___acl_get_file ||
884                                    ktr->ktr_code == SYS___acl_set_file ||
885                                    ktr->ktr_code == SYS___acl_get_fd ||
886                                    ktr->ktr_code == SYS___acl_set_fd ||
887                                    ktr->ktr_code == SYS___acl_delete_file ||
888                                    ktr->ktr_code == SYS___acl_delete_fd ||
889                                    ktr->ktr_code == SYS___acl_aclcheck_file ||
890                                    ktr->ktr_code == SYS___acl_aclcheck_fd ||
891                                    ktr->ktr_code == SYS___acl_get_link ||
892                                    ktr->ktr_code == SYS___acl_set_link ||
893                                    ktr->ktr_code == SYS___acl_delete_link ||
894                                    ktr->ktr_code == SYS___acl_aclcheck_link) {
895                                 print_number(ip,narg,c);
896                                 (void)putchar(',');
897                                 acltypename((int)*ip);
898                                 ip++;
899                                 narg--;
900                         } else if (ktr->ktr_code == SYS_sigaction) {
901                                 (void)putchar('(');
902                                 signame((int)*ip);
903                                 ip++;
904                                 narg--;
905                                 c = ',';
906                         } else if (ktr->ktr_code == SYS_extattrctl) {
907                                 print_number(ip,narg,c);
908                                 (void)putchar(',');
909                                 extattrctlname((int)*ip);
910                                 ip++;
911                                 narg--;
912                         } else if (ktr->ktr_code == SYS_nmount) {
913                                 print_number(ip,narg,c);
914                                 print_number(ip,narg,c);
915                                 (void)putchar(',');
916                                 mountflagsname ((int)*ip);
917                                 ip++;
918                                 narg--;
919                         } else if (ktr->ktr_code == SYS_thr_create) {
920                                 print_number(ip,narg,c);
921                                 print_number(ip,narg,c);
922                                 (void)putchar(',');
923                                 thrcreateflagsname ((int)*ip);
924                                 ip++;
925                                 narg--;
926                         } else if (ktr->ktr_code == SYS_thr_kill) {
927                                 print_number(ip,narg,c);
928                                 (void)putchar(',');
929                                 signame ((int)*ip);
930                                 ip++;
931                                 narg--;
932                         } else if (ktr->ktr_code == SYS_kldunloadf) {
933                                 print_number(ip,narg,c);
934                                 (void)putchar(',');
935                                 kldunloadfflagsname ((int)*ip);
936                                 ip++;
937                                 narg--;
938                         }
939                 }
940                 while (narg > 0) {
941                         print_number(ip,narg,c);
942                 }
943                 (void)putchar(')');
944         }
945         (void)putchar('\n');
946 }
947
948 void
949 ktrsysret(struct ktr_sysret *ktr, u_int flags)
950 {
951         register_t ret = ktr->ktr_retval;
952         int error = ktr->ktr_error;
953         int code = ktr->ktr_code;
954
955         if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
956             (code >= nsyscalls || code < 0))
957                 (void)printf("[%d] ", code);
958         else
959                 (void)printf("%s ", syscallnames[code]);
960
961         if (error == 0) {
962                 if (fancy) {
963                         (void)printf("%ld", (long)ret);
964                         if (ret < 0 || ret > 9)
965                                 (void)printf("/%#lx", (long)ret);
966                 } else {
967                         if (decimal)
968                                 (void)printf("%ld", (long)ret);
969                         else
970                                 (void)printf("%#lx", (long)ret);
971                 }
972         } else if (error == ERESTART)
973                 (void)printf("RESTART");
974         else if (error == EJUSTRETURN)
975                 (void)printf("JUSTRETURN");
976         else {
977                 (void)printf("-1 errno %d", ktr->ktr_error);
978                 if (fancy)
979                         (void)printf(" %s", strerror(ktr->ktr_error));
980         }
981         (void)putchar('\n');
982 }
983
984 void
985 ktrnamei(char *cp, int len)
986 {
987         (void)printf("\"%.*s\"\n", len, cp);
988 }
989
990 void
991 hexdump(char *p, int len, int screenwidth)
992 {
993         int n, i;
994         int width;
995
996         width = 0;
997         do {
998                 width += 2;
999                 i = 13;                 /* base offset */
1000                 i += (width / 2) + 1;   /* spaces every second byte */
1001                 i += (width * 2);       /* width of bytes */
1002                 i += 3;                 /* "  |" */
1003                 i += width;             /* each byte */
1004                 i += 1;                 /* "|" */
1005         } while (i < screenwidth);
1006         width -= 2;
1007
1008         for (n = 0; n < len; n += width) {
1009                 for (i = n; i < n + width; i++) {
1010                         if ((i % width) == 0) { /* beginning of line */
1011                                 printf("       0x%04x", i);
1012                         }
1013                         if ((i % 2) == 0) {
1014                                 printf(" ");
1015                         }
1016                         if (i < len)
1017                                 printf("%02x", p[i] & 0xff);
1018                         else
1019                                 printf("  ");
1020                 }
1021                 printf("  |");
1022                 for (i = n; i < n + width; i++) {
1023                         if (i >= len)
1024                                 break;
1025                         if (p[i] >= ' ' && p[i] <= '~')
1026                                 printf("%c", p[i]);
1027                         else
1028                                 printf(".");
1029                 }
1030                 printf("|\n");
1031         }
1032         if ((i % width) != 0)
1033                 printf("\n");
1034 }
1035
1036 void
1037 visdump(char *dp, int datalen, int screenwidth)
1038 {
1039         int col = 0;
1040         char *cp;
1041         int width;
1042         char visbuf[5];
1043
1044         (void)printf("       \"");
1045         col = 8;
1046         for (;datalen > 0; datalen--, dp++) {
1047                 (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
1048                 cp = visbuf;
1049                 /*
1050                  * Keep track of printables and
1051                  * space chars (like fold(1)).
1052                  */
1053                 if (col == 0) {
1054                         (void)putchar('\t');
1055                         col = 8;
1056                 }
1057                 switch(*cp) {
1058                 case '\n':
1059                         col = 0;
1060                         (void)putchar('\n');
1061                         continue;
1062                 case '\t':
1063                         width = 8 - (col&07);
1064                         break;
1065                 default:
1066                         width = strlen(cp);
1067                 }
1068                 if (col + width > (screenwidth-2)) {
1069                         (void)printf("\\\n\t");
1070                         col = 8;
1071                 }
1072                 col += width;
1073                 do {
1074                         (void)putchar(*cp++);
1075                 } while (*cp);
1076         }
1077         if (col == 0)
1078                 (void)printf("       ");
1079         (void)printf("\"\n");
1080 }
1081
1082 void
1083 ktrgenio(struct ktr_genio *ktr, int len)
1084 {
1085         int datalen = len - sizeof (struct ktr_genio);
1086         char *dp = (char *)ktr + sizeof (struct ktr_genio);
1087         static int screenwidth = 0;
1088         int i, binary;
1089
1090         if (screenwidth == 0) {
1091                 struct winsize ws;
1092
1093                 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1094                     ws.ws_col > 8)
1095                         screenwidth = ws.ws_col;
1096                 else
1097                         screenwidth = 80;
1098         }
1099         printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1100                 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1101                 datalen == 1 ? "" : "s");
1102         if (suppressdata)
1103                 return;
1104         if (maxdata && datalen > maxdata)
1105                 datalen = maxdata;
1106
1107         for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1108                 if (dp[i] >= 32 && dp[i] < 127)
1109                         continue;
1110                 if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1111                         continue;
1112                 binary = 1;
1113         }
1114         if (binary)
1115                 hexdump(dp, datalen, screenwidth);
1116         else
1117                 visdump(dp, datalen, screenwidth);
1118 }
1119
1120 const char *signames[] = {
1121         "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",     /*  1 - 6  */
1122         "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",             /*  7 - 12 */
1123         "PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",         /* 13 - 18 */
1124         "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",           /* 19 - 24 */
1125         "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",        /* 25 - 30 */
1126         "USR2", NULL,                                           /* 31 - 32 */
1127 };
1128
1129 void
1130 ktrpsig(struct ktr_psig *psig)
1131 {
1132         if (psig->signo > 0 && psig->signo < NSIG)
1133                 (void)printf("SIG%s ", signames[psig->signo]);
1134         else
1135                 (void)printf("SIG %d ", psig->signo);
1136         if (psig->action == SIG_DFL)
1137                 (void)printf("SIG_DFL code=0x%x\n", psig->code);
1138         else {
1139                 (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n",
1140                     (u_long)psig->action, psig->mask.__bits[0], psig->code);
1141         }
1142 }
1143
1144 void
1145 ktrcsw(struct ktr_csw *cs)
1146 {
1147         (void)printf("%s %s\n", cs->out ? "stop" : "resume",
1148                 cs->user ? "user" : "kernel");
1149 }
1150
1151 #define UTRACE_DLOPEN_START             1
1152 #define UTRACE_DLOPEN_STOP              2
1153 #define UTRACE_DLCLOSE_START            3
1154 #define UTRACE_DLCLOSE_STOP             4
1155 #define UTRACE_LOAD_OBJECT              5
1156 #define UTRACE_UNLOAD_OBJECT            6
1157 #define UTRACE_ADD_RUNDEP               7
1158 #define UTRACE_PRELOAD_FINISHED         8
1159 #define UTRACE_INIT_CALL                9
1160 #define UTRACE_FINI_CALL                10
1161
1162 struct utrace_rtld {
1163         char sig[4];                            /* 'RTLD' */
1164         int event;
1165         void *handle;
1166         void *mapbase;
1167         size_t mapsize;
1168         int refcnt;
1169         char name[MAXPATHLEN];
1170 };
1171
1172 void
1173 ktruser_rtld(int len, unsigned char *p)
1174 {
1175         struct utrace_rtld *ut = (struct utrace_rtld *)p;
1176         void *parent;
1177         int mode;
1178
1179         switch (ut->event) {
1180         case UTRACE_DLOPEN_START:
1181                 mode = ut->refcnt;
1182                 printf("dlopen(%s, ", ut->name);
1183                 switch (mode & RTLD_MODEMASK) {
1184                 case RTLD_NOW:
1185                         printf("RTLD_NOW");
1186                         break;
1187                 case RTLD_LAZY:
1188                         printf("RTLD_LAZY");
1189                         break;
1190                 default:
1191                         printf("%#x", mode & RTLD_MODEMASK);
1192                 }
1193                 if (mode & RTLD_GLOBAL)
1194                         printf(" | RTLD_GLOBAL");
1195                 if (mode & RTLD_TRACE)
1196                         printf(" | RTLD_TRACE");
1197                 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1198                         printf(" | %#x", mode &
1199                             ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1200                 printf(")\n");
1201                 break;
1202         case UTRACE_DLOPEN_STOP:
1203                 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1204                     ut->refcnt);
1205                 break;
1206         case UTRACE_DLCLOSE_START:
1207                 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1208                     ut->refcnt);
1209                 break;
1210         case UTRACE_DLCLOSE_STOP:
1211                 printf("dlclose(%p) finished\n", ut->handle);
1212                 break;
1213         case UTRACE_LOAD_OBJECT:
1214                 printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1215                     ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1216                     ut->name);
1217                 break;
1218         case UTRACE_UNLOAD_OBJECT:
1219                 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1220                     ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1221                     ut->name);
1222                 break;
1223         case UTRACE_ADD_RUNDEP:
1224                 parent = ut->mapbase;
1225                 printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1226                     ut->handle, ut->name, ut->refcnt);
1227                 break;
1228         case UTRACE_PRELOAD_FINISHED:
1229                 printf("RTLD: LD_PRELOAD finished\n");
1230                 break;
1231         case UTRACE_INIT_CALL:
1232                 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1233                     ut->name);
1234                 break;
1235         case UTRACE_FINI_CALL:
1236                 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1237                     ut->name);
1238                 break;
1239         default:
1240                 p += 4;
1241                 len -= 4;
1242                 printf("RTLD: %d ", len);
1243                 while (len--)
1244                         if (decimal)
1245                                 printf(" %d", *p++);
1246                         else
1247                                 printf(" %02x", *p++);
1248                 printf("\n");
1249         }
1250 }
1251
1252 struct utrace_malloc {
1253         void *p;
1254         size_t s;
1255         void *r;
1256 };
1257
1258 void
1259 ktruser_malloc(int len, unsigned char *p)
1260 {
1261         struct utrace_malloc *ut = (struct utrace_malloc *)p;
1262
1263         if (ut->p == (void *)(intptr_t)(-1))
1264                 printf("malloc_init()\n");
1265         else if (ut->s == 0)
1266                 printf("free(%p)\n", ut->p);
1267         else if (ut->p == NULL)
1268                 printf("%p = malloc(%zu)\n", ut->r, ut->s);
1269         else
1270                 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1271 }
1272
1273 void
1274 ktruser(int len, unsigned char *p)
1275 {
1276
1277         if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1278                 ktruser_rtld(len, p);
1279                 return;
1280         }
1281
1282         if (len == sizeof(struct utrace_malloc)) {
1283                 ktruser_malloc(len, p);
1284                 return;
1285         }
1286
1287         (void)printf("%d ", len);
1288         while (len--)
1289                 if (decimal)
1290                         (void)printf(" %d", *p++);
1291                 else
1292                         (void)printf(" %02x", *p++);
1293         (void)printf("\n");
1294 }
1295
1296 void
1297 ktrsockaddr(struct sockaddr *sa)
1298 {
1299 /*
1300  TODO: Support additional address families
1301         #include <netnatm/natm.h>
1302         struct sockaddr_natm    *natm;
1303         #include <netsmb/netbios.h>
1304         struct sockaddr_nb      *nb;
1305 */
1306         char addr[64];
1307
1308         /*
1309          * note: ktrstruct() has already verified that sa points to a
1310          * buffer at least sizeof(struct sockaddr) bytes long and exactly
1311          * sa->sa_len bytes long.
1312          */
1313         printf("struct sockaddr { ");
1314         sockfamilyname(sa->sa_family);
1315         printf(", ");
1316
1317 #define check_sockaddr_len(n)                                   \
1318         if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \
1319                 printf("invalid");                              \
1320                 break;                                          \
1321         }
1322
1323         switch(sa->sa_family) {
1324         case AF_INET: {
1325                 struct sockaddr_in      *sa_in;
1326
1327                 sa_in = (struct sockaddr_in *)sa;
1328                 check_sockaddr_len(in);
1329                 inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);
1330                 printf("%s:%u", addr, ntohs(sa_in->sin_port));
1331                 break;
1332         }
1333 #ifdef NETATALK
1334         case AF_APPLETALK: {
1335                 struct sockaddr_at      *sa_at;
1336                 struct netrange         *nr;
1337
1338                 sa_at = (struct sockaddr_at *)sa;
1339                 check_sockaddr_len(at);
1340                 nr = &sa_at->sat_range.r_netrange;
1341                 printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net),
1342                         sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet),
1343                         ntohs(nr->nr_lastnet), nr->nr_phase);
1344                 break;
1345         }
1346 #endif
1347         case AF_INET6: {
1348                 struct sockaddr_in6     *sa_in6;
1349
1350                 sa_in6 = (struct sockaddr_in6 *)sa;
1351                 check_sockaddr_len(in6);
1352                 inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);
1353                 printf("[%s]:%u", addr, htons(sa_in6->sin6_port));
1354                 break;
1355         }
1356 #ifdef IPX
1357         case AF_IPX: {
1358                 struct sockaddr_ipx     *sa_ipx;
1359
1360                 sa_ipx = (struct sockaddr_ipx *)sa;
1361                 check_sockaddr_len(ipx);
1362                 /* XXX wish we had ipx_ntop */
1363                 printf("%s", ipx_ntoa(sa_ipx->sipx_addr));
1364                 break;
1365         }
1366 #endif
1367         case AF_UNIX: {
1368                 struct sockaddr_un *sa_un;
1369
1370                 sa_un = (struct sockaddr_un *)sa;
1371                 check_sockaddr_len(un);
1372                 printf("%.*s", (int)sizeof(sa_un->sun_path), sa_un->sun_path);
1373                 break;
1374         }
1375         default:
1376                 printf("unknown address family");
1377         }
1378         printf(" }\n");
1379 }
1380
1381 void
1382 ktrstat(struct stat *statp)
1383 {
1384         char mode[12], timestr[PATH_MAX + 4];
1385         struct passwd *pwd;
1386         struct group  *grp;
1387         struct tm *tm;
1388
1389         /*
1390          * note: ktrstruct() has already verified that statp points to a
1391          * buffer exactly sizeof(struct stat) bytes long.
1392          */
1393         printf("struct stat {");
1394         strmode(statp->st_mode, mode);
1395         printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
1396                 (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
1397                 (uintmax_t)statp->st_nlink);
1398         if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1399                 printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1400         else
1401                 printf("uid=\"%s\", ", pwd->pw_name);
1402         if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1403                 printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1404         else
1405                 printf("gid=\"%s\", ", grp->gr_name);
1406         printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1407         printf("atime=");
1408         if (resolv == 0)
1409                 printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1410         else {
1411                 tm = localtime(&statp->st_atim.tv_sec);
1412                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1413                 printf("\"%s\"", timestr);
1414         }
1415         if (statp->st_atim.tv_nsec != 0)
1416                 printf(".%09ld, ", statp->st_atim.tv_nsec);
1417         else
1418                 printf(", ");
1419         printf("stime=");
1420         if (resolv == 0)
1421                 printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1422         else {
1423                 tm = localtime(&statp->st_mtim.tv_sec);
1424                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1425                 printf("\"%s\"", timestr);
1426         }
1427         if (statp->st_mtim.tv_nsec != 0)
1428                 printf(".%09ld, ", statp->st_mtim.tv_nsec);
1429         else
1430                 printf(", ");
1431         printf("ctime=");
1432         if (resolv == 0)
1433                 printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1434         else {
1435                 tm = localtime(&statp->st_ctim.tv_sec);
1436                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1437                 printf("\"%s\"", timestr);
1438         }
1439         if (statp->st_ctim.tv_nsec != 0)
1440                 printf(".%09ld, ", statp->st_ctim.tv_nsec);
1441         else
1442                 printf(", ");
1443         printf("birthtime=");
1444         if (resolv == 0)
1445                 printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1446         else {
1447                 tm = localtime(&statp->st_birthtim.tv_sec);
1448                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1449                 printf("\"%s\"", timestr);
1450         }
1451         if (statp->st_birthtim.tv_nsec != 0)
1452                 printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1453         else
1454                 printf(", ");
1455         printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1456                 (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1457                 (intmax_t)statp->st_blocks, statp->st_flags);
1458         printf(" }\n");
1459 }
1460
1461 void
1462 ktrstruct(char *buf, size_t buflen)
1463 {
1464         char *name, *data;
1465         size_t namelen, datalen;
1466         int i;
1467         struct stat sb;
1468         struct sockaddr_storage ss;
1469
1470         for (name = buf, namelen = 0;
1471              namelen < buflen && name[namelen] != '\0';
1472              ++namelen)
1473                 /* nothing */;
1474         if (namelen == buflen)
1475                 goto invalid;
1476         if (name[namelen] != '\0')
1477                 goto invalid;
1478         data = buf + namelen + 1;
1479         datalen = buflen - namelen - 1;
1480         if (datalen == 0)
1481                 goto invalid;
1482         /* sanity check */
1483         for (i = 0; i < namelen; ++i)
1484                 if (!isalpha((unsigned char)name[i]))
1485                         goto invalid;
1486         if (strcmp(name, "stat") == 0) {
1487                 if (datalen != sizeof(struct stat))
1488                         goto invalid;
1489                 memcpy(&sb, data, datalen);
1490                 ktrstat(&sb);
1491         } else if (strcmp(name, "sockaddr") == 0) {
1492                 if (datalen > sizeof(ss))
1493                         goto invalid;
1494                 memcpy(&ss, data, datalen);
1495                 if (datalen < sizeof(struct sockaddr) ||
1496                     datalen != ss.ss_len)
1497                         goto invalid;
1498                 ktrsockaddr((struct sockaddr *)&ss);
1499         } else {
1500                 printf("unknown structure\n");
1501         }
1502         return;
1503 invalid:
1504         printf("invalid record\n");
1505 }
1506
1507 #if defined(__amd64__) || defined(__i386__)
1508 void
1509 linux_ktrsyscall(struct ktr_syscall *ktr)
1510 {
1511         int narg = ktr->ktr_narg;
1512         register_t *ip;
1513
1514         if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1515                 printf("[%d]", ktr->ktr_code);
1516         else
1517                 printf("%s", linux_syscallnames[ktr->ktr_code]);
1518         ip = &ktr->ktr_args[0];
1519         if (narg) {
1520                 char c = '(';
1521                 while (narg > 0)
1522                         print_number(ip, narg, c);
1523                 putchar(')');
1524         }
1525         putchar('\n');
1526 }
1527
1528 void
1529 linux_ktrsysret(struct ktr_sysret *ktr)
1530 {
1531         register_t ret = ktr->ktr_retval;
1532         int error = ktr->ktr_error;
1533         int code = ktr->ktr_code;
1534
1535         if (code >= nlinux_syscalls || code < 0)
1536                 printf("[%d] ", code);
1537         else
1538                 printf("%s ", linux_syscallnames[code]);
1539
1540         if (error == 0) {
1541                 if (fancy) {
1542                         printf("%ld", (long)ret);
1543                         if (ret < 0 || ret > 9)
1544                                 printf("/%#lx", (long)ret);
1545                 } else {
1546                         if (decimal)
1547                                 printf("%ld", (long)ret);
1548                         else
1549                                 printf("%#lx", (long)ret);
1550                 }
1551         } else if (error == ERESTART)
1552                 printf("RESTART");
1553         else if (error == EJUSTRETURN)
1554                 printf("JUSTRETURN");
1555         else {
1556                 if (ktr->ktr_error <= ELAST + 1)
1557                         error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1558                 else
1559                         error = 999;
1560                 printf("-1 errno %d", error);
1561                 if (fancy)
1562                         printf(" %s", strerror(ktr->ktr_error));
1563         }
1564         putchar('\n');
1565 }
1566 #endif
1567
1568 void
1569 usage(void)
1570 {
1571         fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1572             "[-m maxdata] [-p pid] [-t trstr]\n");
1573         exit(1);
1574 }