127ec61ajhb/*
227ec61ajhb * Copyright (c) 2006 "David Kirchner" <dpk@dpk.net>. All rights reserved.
327ec61ajhb *
427ec61ajhb * Redistribution and use in source and binary forms, with or without
527ec61ajhb * modification, are permitted provided that the following conditions
627ec61ajhb * are met:
727ec61ajhb * 1. Redistributions of source code must retain the above copyright
827ec61ajhb *    notice, this list of conditions and the following disclaimer.
927ec61ajhb * 2. Redistributions in binary form must reproduce the above copyright
1027ec61ajhb *    notice, this list of conditions and the following disclaimer in the
1127ec61ajhb *    documentation and/or other materials provided with the distribution.
1227ec61ajhb *
1327ec61ajhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1427ec61ajhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1527ec61ajhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1627ec61ajhb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1727ec61ajhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1827ec61ajhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1927ec61ajhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2027ec61ajhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2127ec61ajhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2227ec61ajhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2327ec61ajhb * SUCH DAMAGE.
2427ec61ajhb */
2527ec61ajhb
2627ec61ajhb#include <sys/cdefs.h>
2727ec61ajhb__FBSDID("$FreeBSD$");
2827ec61ajhb
2927ec61ajhb#define L2CAP_SOCKET_CHECKED
3027ec61ajhb
3127ec61ajhb#include <sys/types.h>
3227ec61ajhb#include <sys/acl.h>
3327ec61ajhb#include <sys/capsicum.h>
34bac78aajhb#include <sys/event.h>
3527ec61ajhb#include <sys/extattr.h>
3627ec61ajhb#include <sys/linker.h>
3727ec61ajhb#include <sys/mman.h>
3827ec61ajhb#include <sys/mount.h>
3927ec61ajhb#include <sys/procctl.h>
4027ec61ajhb#include <sys/ptrace.h>
4127ec61ajhb#include <sys/reboot.h>
4227ec61ajhb#include <sys/resource.h>
4327ec61ajhb#include <sys/rtprio.h>
4427ec61ajhb#include <sys/sem.h>
4527ec61ajhb#include <sys/shm.h>
4627ec61ajhb#include <sys/socket.h>
4727ec61ajhb#include <sys/stat.h>
4827ec61ajhb#include <sys/thr.h>
4927ec61ajhb#include <sys/umtx.h>
507735433jhb#include <machine/sysarch.h>
5127ec61ajhb#include <netinet/in.h>
5259713b3tuexen#include <netinet/sctp.h>
5327ec61ajhb#include <netinet/tcp.h>
5427ec61ajhb#include <netinet/udp.h>
5589fb1ddtuexen#include <netinet/udplite.h>
5627ec61ajhb#include <nfsserver/nfs.h>
5727ec61ajhb#include <ufs/ufs/quota.h>
58a8429c6smh#include <vm/vm.h>
5927ec61ajhb#include <vm/vm_param.h>
6027ec61ajhb#include <aio.h>
6127ec61ajhb#include <fcntl.h>
6227ec61ajhb#include <sched.h>
6327ec61ajhb#include <stdbool.h>
6427ec61ajhb#include <stdio.h>
6527ec61ajhb#include <stdlib.h>
6627ec61ajhb#include <strings.h>
6727ec61ajhb#include <sysdecode.h>
6827ec61ajhb#include <unistd.h>
6927ec61ajhb#include <sys/bitstring.h>
7027ec61ajhb#include <netgraph/bluetooth/include/ng_hci.h>
7127ec61ajhb#include <netgraph/bluetooth/include/ng_l2cap.h>
7227ec61ajhb#include <netgraph/bluetooth/include/ng_btsocket.h>
7327ec61ajhb
7427ec61ajhb/*
7527ec61ajhb * This is taken from the xlat tables originally in truss which were
7627ec61ajhb * in turn taken from strace.
7727ec61ajhb */
7827ec61ajhbstruct name_table {
7927ec61ajhb	uintmax_t val;
8027ec61ajhb	const char *str;
8127ec61ajhb};
8227ec61ajhb
8327ec61ajhb#define	X(a)	{ a, #a },
8427ec61ajhb#define	XEND	{ 0, NULL }
8527ec61ajhb
8627ec61ajhb#define	TABLE_START(n)	static struct name_table n[] = {
8727ec61ajhb#define	TABLE_ENTRY	X
8827ec61ajhb#define	TABLE_END	XEND };
8927ec61ajhb
9027ec61ajhb#include "tables.h"
9127ec61ajhb
9227ec61ajhb#undef TABLE_START
9327ec61ajhb#undef TABLE_ENTRY
9427ec61ajhb#undef TABLE_END
9527ec61ajhb
9627ec61ajhb/*
9727ec61ajhb * These are simple support macros. print_or utilizes a variable
9827ec61ajhb * defined in the calling function to track whether or not it should
9927ec61ajhb * print a logical-OR character ('|') before a string. if_print_or
10027ec61ajhb * simply handles the necessary "if" statement used in many lines
10127ec61ajhb * of this file.
10227ec61ajhb */
10327ec61ajhb#define print_or(fp,str,orflag) do {                     \
10427ec61ajhb	if (orflag) fputc(fp, '|'); else orflag = true;  \
10527ec61ajhb	fprintf(fp, str); }                              \
10627ec61ajhb	while (0)
10727ec61ajhb#define if_print_or(fp,i,flag,orflag) do {         \
10827ec61ajhb	if ((i & flag) == flag)                    \
10927ec61ajhb	print_or(fp,#flag,orflag); }               \
11027ec61ajhb	while (0)
11127ec61ajhb
11227ec61ajhbstatic const char *
11327ec61ajhblookup_value(struct name_table *table, uintmax_t val)
11427ec61ajhb{
11527ec61ajhb
11627ec61ajhb	for (; table->str != NULL; table++)
11727ec61ajhb		if (table->val == val)
11827ec61ajhb			return (table->str);
11927ec61ajhb	return (NULL);
12027ec61ajhb}
12127ec61ajhb
12227ec61ajhb/*
12327ec61ajhb * Used when the value maps to a bitmask of #definition values in the
12427ec61ajhb * table.  This is a helper routine which outputs a symbolic mask of
12527ec61ajhb * matched masks.  Multiple masks are separated by a pipe ('|').
12627ec61ajhb * The value is modified on return to only hold unmatched bits.
12727ec61ajhb */
12827ec61ajhbstatic void
12927ec61ajhbprint_mask_part(FILE *fp, struct name_table *table, uintmax_t *valp,
13027ec61ajhb    bool *printed)
13127ec61ajhb{
13227ec61ajhb	uintmax_t rem;
13327ec61ajhb
13427ec61ajhb	rem = *valp;
13527ec61ajhb	for (; table->str != NULL; table++) {
13627ec61ajhb		if ((table->val & rem) == table->val) {
13727ec61ajhb			/*
13827ec61ajhb			 * Only print a zero mask if the raw value is
13927ec61ajhb			 * zero.
14027ec61ajhb			 */
14127ec61ajhb			if (table->val == 0 && *valp != 0)
14227ec61ajhb				continue;
14327ec61ajhb			fprintf(fp, "%s%s", *printed ? "|" : "", table->str);
14427ec61ajhb			*printed = true;
14527ec61ajhb			rem &= ~table->val;
14627ec61ajhb		}
14727ec61ajhb	}
14827ec61ajhb
14927ec61ajhb	*valp = rem;
15027ec61ajhb}
15127ec61ajhb
15227ec61ajhb/*
15327ec61ajhb * Used when the value maps to a bitmask of #definition values in the
15427ec61ajhb * table.  The return value is true if something was printed.  If
15527ec61ajhb * rem is not NULL, *rem holds any bits not decoded if something was
15627ec61ajhb * printed.  If nothing was printed and rem is not NULL, *rem holds
15727ec61ajhb * the original value.
15827ec61ajhb */
15927ec61ajhbstatic bool
16027ec61ajhbprint_mask_int(FILE *fp, struct name_table *table, int ival, int *rem)
16127ec61ajhb{
162