diff options
| author | Julian Elischer <julian@FreeBSD.org> | 2002-11-20 23:01:59 +0000 |
|---|---|---|
| committer | Julian Elischer <julian@FreeBSD.org> | 2002-11-20 23:01:59 +0000 |
| commit | 878ed22696d5402cabd6f90932cc970ab912b7b0 (patch) | |
| tree | c38e3c48c390af16003a1f451848e93558978422 /usr.bin | |
| parent | 2699228f1effe6a9d4c53e0b065a8f37097ebf8d (diff) | |
Notes
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/bluetooth/Makefile | 5 | ||||
| -rw-r--r-- | usr.bin/bluetooth/btsockstat/Makefile | 17 | ||||
| -rw-r--r-- | usr.bin/bluetooth/btsockstat/btsockstat.1 | 73 | ||||
| -rw-r--r-- | usr.bin/bluetooth/btsockstat/btsockstat.c | 484 |
4 files changed, 579 insertions, 0 deletions
diff --git a/usr.bin/bluetooth/Makefile b/usr.bin/bluetooth/Makefile new file mode 100644 index 0000000000000..1da9ef21cc2a0 --- /dev/null +++ b/usr.bin/bluetooth/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ +SUBDIR= btsockstat + +.include <bsd.subdir.mk> + diff --git a/usr.bin/bluetooth/btsockstat/Makefile b/usr.bin/bluetooth/btsockstat/Makefile new file mode 100644 index 0000000000000..ea78892de4a73 --- /dev/null +++ b/usr.bin/bluetooth/btsockstat/Makefile @@ -0,0 +1,17 @@ +# $Id: Makefile,v 1.1.1.1 2002/09/09 16:12:49 max Exp $ +# $FreeBSD$ + +PROG= btsockstat +MAN1= btsockstat.1 + +DESTDIR= /usr/bin/ +MANDIR= ../share/man/man + +WARNS?= 2 +CFLAGS+= -g -I../../../sys/netgraph/bluetooth/include/ + +SRCS= btsockstat.c +DPADD= ${LIBKVM} +LDADD= -lkvm + +.include <bsd.prog.mk> diff --git a/usr.bin/bluetooth/btsockstat/btsockstat.1 b/usr.bin/bluetooth/btsockstat/btsockstat.1 new file mode 100644 index 0000000000000..a1295cd9f703a --- /dev/null +++ b/usr.bin/bluetooth/btsockstat/btsockstat.1 @@ -0,0 +1,73 @@ +.\" btsockstat.1 +.\" +.\" Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: btsockstat.1,v 1.2 2002/11/12 17:08:34 max Exp $ +.\" $FreeBSD$ +.Dd August 31, 2002 +.Dt BTSOCKSTAT 1 +.Os +.Sh NAME +.Nm btsockstat +.Nd show Bluetooth sockets information +.Sh SYNOPSIS +.Nm +.Op Fl p Ar protocol +.Op Fl r +.Op Fl M Ar core +.Sh DESCRIPTION +The +.Nm +command symbolically displays the contents of various Bluetooth sockets +related data structures. There are few output formats, depending on the +options for the information presented. +.Nm +will print results to the standard output and error messages to the +standard error. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl p Ar protocol +Display a list of active sockets (protocol control blocks) for each +specified protocol. Supported protocols are: +.Cm hci_raw , l2cap_raw +and +.Cm l2cap . +.It Fl r +Display a list of active routing entries (if any) for specified protocol. +.It Fl M Ar core +Extract values associated with the name list from the specified core +instead of the default +.Pa /dev/kmem. +.El +.Sh BUGS +Most likely. Please report if found. +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr ng_btsocket 4 +.Sh AUTHORS +.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com + diff --git a/usr.bin/bluetooth/btsockstat/btsockstat.c b/usr.bin/bluetooth/btsockstat/btsockstat.c new file mode 100644 index 0000000000000..d123502ddc652 --- /dev/null +++ b/usr.bin/bluetooth/btsockstat/btsockstat.c @@ -0,0 +1,484 @@ +/* + * btsockstat.c + * + * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: btsockstat.c,v 1.2 2002/09/16 19:40:14 max Exp $ + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/callout.h> +#include <sys/param.h> +#include <sys/queue.h> +#include <sys/socket.h> +#include <sys/socketvar.h> + +#include <net/if.h> +#include <net/if_var.h> + +#include <bitstring.h> +#include <err.h> +#include <fcntl.h> +#include <kvm.h> +#include <limits.h> + +#include <ng_hci.h> +#include <ng_l2cap.h> +#include <ng_btsocket.h> +#include <ng_btsocket_hci_raw.h> +#include <ng_btsocket_l2cap.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static void hcirawpr (kvm_t *kvmd, u_long addr); +static void l2caprawpr (kvm_t *kvmd, u_long addr); +static void l2cappr (kvm_t *kvmd, u_long addr); +static void l2caprtpr (kvm_t *kvmd, u_long addr); + +static kvm_t * kopen (char const *memf); +static int kread (kvm_t *kvmd, u_long addr, char *buffer, int size); + +static void usage (void); + +/* + * List of symbols + */ + +static struct nlist nl[] = { +#define N_HCI_RAW 0 + { "_ng_btsocket_hci_raw_sockets" }, +#define N_L2CAP_RAW 1 + { "_ng_btsocket_l2cap_raw_sockets" }, +#define N_L2CAP 2 + { "_ng_btsocket_l2cap_sockets" }, +#define N_L2CAP_RAW_RT 3 + { "_ng_btsocket_l2cap_raw_rt" }, +#define N_L2CAP_RT 4 + { "_ng_btsocket_l2cap_rt" }, + { "" }, +}; + +/* + * Main + */ + +int +main(int argc, char *argv[]) +{ + int opt, proto = -1, route = 0; + kvm_t *kvmd = NULL; + char *memf = NULL; + + while ((opt = getopt(argc, argv, "hM:p:r")) != -1) { + switch (opt) { + case 'M': + memf = optarg; + break; + + case 'p': + if (strcasecmp(optarg, "hci_raw") == 0) + proto = N_HCI_RAW; + else if (strcasecmp(optarg, "l2cap_raw") == 0) + proto = N_L2CAP_RAW; + else if (strcasecmp(optarg, "l2cap") == 0) + proto = N_L2CAP; + else + usage(); + /* NOT REACHED */ + break; + + case 'r': + route = 1; + break; + + case 'h': + default: + usage(); + /* NOT REACHED */ + } + } + + if (proto == N_HCI_RAW && route) + usage(); + /* NOT REACHED */ + + kvmd = kopen(memf); + if (kvmd == NULL) + return (1); + + switch (proto) { + case N_HCI_RAW: + hcirawpr(kvmd, nl[N_HCI_RAW].n_value); + break; + + case N_L2CAP_RAW: + if (route) + l2caprtpr(kvmd, nl[N_L2CAP_RAW_RT].n_value); + else + l2caprawpr(kvmd, nl[N_L2CAP_RAW].n_value); + break; + + case N_L2CAP: + if (route) + l2caprtpr(kvmd, nl[N_L2CAP_RT].n_value); + else + l2cappr(kvmd, nl[N_L2CAP].n_value); + break; + + default: + if (route) { + l2caprtpr(kvmd, nl[N_L2CAP_RAW_RT].n_value); + l2caprtpr(kvmd, nl[N_L2CAP_RT].n_value); + } else { + hcirawpr(kvmd, nl[N_HCI_RAW].n_value); + l2caprawpr(kvmd, nl[N_L2CAP_RAW].n_value); + l2cappr(kvmd, nl[N_L2CAP].n_value); + } + break; + } + + return (kvm_close(kvmd)); +} /* main */ + +/* + * Print raw HCI sockets + */ + +static void +hcirawpr(kvm_t *kvmd, u_long addr) +{ + ng_btsocket_hci_raw_pcb_p this = NULL, next = NULL; + ng_btsocket_hci_raw_pcb_t pcb; + struct socket so; + int first = 1; + + if (addr == 0) + return; + + if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) + return; + + for ( ; this != NULL; this = next) { + if (kread(kvmd, (u_long) this, (char *) &pcb, sizeof(pcb)) < 0) + return; + if (kread(kvmd, (u_long) pcb.so, (char *) &so, sizeof(so)) < 0) + return; + + next = LIST_NEXT(&pcb, next); + + if (first) { + first = 0; + fprintf(stdout, +"Active raw HCI sockets\n" \ +"%-8.8s %-8.8s %-6.6s %-6.6s %-6.6s %-16.16s\n", + "Socket", + "PCB", + "Flags", + "Recv-Q", + "Send-Q", + "Local address"); + } + + if (pcb.addr.hci_node[0] == 0) { + pcb.addr.hci_node[0] = '*'; + pcb.addr.hci_node[1] = 0; + } + + fprintf(stdout, +"%-8.8x %-8.8x %-6.6x %6d %6d %-16.16s\n", + (int) pcb.so, + (int) this, + pcb.flags, + so.so_rcv.sb_cc, + so.so_snd.sb_cc, + pcb.addr.hci_node); + } +} /* hcirawpr */ + +/* + * Print raw L2CAP sockets + */ + +static void +l2caprawpr(kvm_t *kvmd, u_long addr) +{ + ng_btsocket_l2cap_raw_pcb_p this = NULL, next = NULL; + ng_btsocket_l2cap_raw_pcb_t pcb; + struct socket so; + int first = 1; + char bdaddr[32]; + + if (addr == 0) + return; + + if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) + return; + + for ( ; this != NULL; this = next) { + if (kread(kvmd, (u_long) this, (char *) &pcb, sizeof(pcb)) < 0) + return; + if (kread(kvmd, (u_long) pcb.so, (char *) &so, sizeof(so)) < 0) + return; + + next = LIST_NEXT(&pcb, next); + + if (first) { + first = 0; + fprintf(stdout, +"Active raw L2CAP sockets\n" \ +"%-8.8s %-8.8s %-6.6s %-6.6s %-18.18s\n", + "Socket", + "PCB", + "Recv-Q", + "Send-Q", + "Local address"); + } + + if (memcmp(&pcb.src, NG_HCI_BDADDR_ANY, sizeof(pcb.src)) == 0) { + bdaddr[0] = '*'; + bdaddr[1] = 0; + } else + snprintf(bdaddr, sizeof(bdaddr), +"%02x:%02x:%02x:%02x:%02x:%02x", + pcb.src.b[5], pcb.src.b[4], pcb.src.b[3], + pcb.src.b[2], pcb.src.b[1], pcb.src.b[0]); + + fprintf(stdout, +"%-8.8x %-8.8x %6d %6d %-18.18s\n", + (int) pcb.so, + (int) this, + so.so_rcv.sb_cc, + so.so_snd.sb_cc, + bdaddr); + } +} /* l2caprawpr */ + +/* + * Print L2CAP sockets + */ + +static void +l2cappr(kvm_t *kvmd, u_long addr) +{ + static char const * const states[] = { + /* NG_BTSOCKET_L2CAP_CLOSED */ "CLOSED", + /* NG_BTSOCKET_L2CAP_CONNECTING */ "CON", + /* NG_BTSOCKET_L2CAP_CONFIGURING */ "CONFIG", + /* NG_BTSOCKET_L2CAP_OPEN */ "OPEN", + /* NG_BTSOCKET_L2CAP_DISCONNECTING */ "DISCON" + }; +#define state2str(x) \ + (((x) >= sizeof(states)/sizeof(states[0]))? "UNKNOWN" : states[(x)]) + + ng_btsocket_l2cap_pcb_p this = NULL, next = NULL; + ng_btsocket_l2cap_pcb_t pcb; + struct socket so; + int first = 1; + char local[32], remote[32]; + + + if (addr == 0) + return; + + if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) + return; + + for ( ; this != NULL; this = next) { + if (kread(kvmd, (u_long) this, (char *) &pcb, sizeof(pcb)) < 0) + return; + if (kread(kvmd, (u_long) pcb.so, (char *) &so, sizeof(so)) < 0) + return; + + next = LIST_NEXT(&pcb, next); + + if (first) { + first = 0; + fprintf(stdout, +"Active L2CAP sockets\n" \ +"%-8.8s %-6.6s %-6.6s %-24.24s %-18.18s %-5.5s %s\n", + "PCB", + "Recv-Q", + "Send-Q", + "Local address/PSM", + "Foreign address", + "CID", + "State"); + } + + if (memcmp(&pcb.src, NG_HCI_BDADDR_ANY, sizeof(pcb.src)) == 0) + snprintf(local, sizeof(local), "*/%d", pcb.psm); + else + snprintf(local, sizeof(local), +"%02x:%02x:%02x:%02x:%02x:%02x/%d", + pcb.src.b[5], pcb.src.b[4], pcb.src.b[3], + pcb.src.b[2], pcb.src.b[1], pcb.src.b[0], + pcb.psm); + + if (memcmp(&pcb.dst, NG_HCI_BDADDR_ANY, sizeof(pcb.dst)) == 0) { + remote[0] = '*'; + remote[1] = 0; + } else + snprintf(remote, sizeof(remote), +"%02x:%02x:%02x:%02x:%02x:%02x", + pcb.dst.b[5], pcb.dst.b[4], pcb.dst.b[3], + pcb.dst.b[2], pcb.dst.b[1], pcb.dst.b[0]); + + fprintf(stdout, +"%-8.8x %6d %6d %-24.24s %-18.18s %-5d %s\n", + (int) this, + so.so_rcv.sb_cc, + so.so_snd.sb_cc, + local, + remote, + pcb.cid, + (so.so_options & SO_ACCEPTCONN)? + "LISTEN" : state2str(pcb.state)); + } +} /* l2cappr */ + +/* + * Print L2CAP routing table + */ + +static void +l2caprtpr(kvm_t *kvmd, u_long addr) +{ + ng_btsocket_l2cap_rtentry_p this = NULL, next = NULL; + ng_btsocket_l2cap_rtentry_t rt; + int first = 1; + char bdaddr[32]; + + if (addr == 0) + return; + + if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) + return; + + for ( ; this != NULL; this = next) { + if (kread(kvmd, (u_long) this, (char *) &rt, sizeof(rt)) < 0) + return; + + next = LIST_NEXT(&rt, next); + + if (first) { + first = 0; + fprintf(stdout, +"Known %sL2CAP routes\n", (addr == nl[N_L2CAP_RAW_RT].n_value)? "raw " : ""); + fprintf(stdout, +"%-8.8s %-8.8s %-18.18s\n", "RTentry", + "Hook", + "BD_ADDR"); + } + + if (memcmp(&rt.src, NG_HCI_BDADDR_ANY, sizeof(rt.src)) == 0) { + bdaddr[0] = '-'; + bdaddr[1] = 0; + } else + snprintf(bdaddr, sizeof(bdaddr), +"%02x:%02x:%02x:%02x:%02x:%02x", rt.src.b[5], rt.src.b[4], rt.src.b[3], + rt.src.b[2], rt.src.b[1], rt.src.b[0]); + + fprintf(stdout, +"%-8.8x %-8.8x %-18.18s\n", + (int) this, + (int) rt.hook, + bdaddr); + } +} /* l2caprtpr */ + +/* + * Open kvm + */ + +static kvm_t * +kopen(char const *memf) +{ + kvm_t *kvmd = NULL; + char errbuf[_POSIX2_LINE_MAX]; + + /* + * Discard setgid privileges if not the running kernel so that + * bad guys can't print interesting stuff from kernel memory. + */ + + if (memf != NULL) + setgid(getgid()); + + kvmd = kvm_openfiles(NULL, memf, NULL, O_RDONLY, errbuf); + if (kvmd == NULL) { + warnx("kvm_openfiles: %s", errbuf); + return (NULL); + } + + if (kvm_nlist(kvmd, nl) < 0) { + warnx("kvm_nlist: %s", kvm_geterr(kvmd)); + goto fail; + } + + if (nl[0].n_type == 0) { + warnx("kvm_nlist: no namelist"); + goto fail; + } + + return (kvmd); +fail: + kvm_close(kvmd); + + return (NULL); +} /* kopen */ + +/* + * Read kvm + */ + +static int +kread(kvm_t *kvmd, u_long addr, char *buffer, int size) +{ + if (kvmd == NULL || buffer == NULL) + return (-1); + + if (kvm_read(kvmd, addr, buffer, size) != size) { + warnx("kvm_read: %s", kvm_geterr(kvmd)); + return (-1); + } + + return (0); +} /* kread */ + +/* + * Print usage and exit + */ + +static void +usage(void) +{ + fprintf(stdout, "Usage: btsockstat [-M core ] [-p proto] [-r]\n"); + exit(255); +} /* usage */ + |
