diff options
Diffstat (limited to 'usr.sbin')
37 files changed, 2194 insertions, 394 deletions
diff --git a/usr.sbin/bluetooth/Makefile b/usr.sbin/bluetooth/Makefile index 821a0035cb44..4a675a4a974d 100644 --- a/usr.sbin/bluetooth/Makefile +++ b/usr.sbin/bluetooth/Makefile @@ -1,12 +1,15 @@ -# $Id$ +# $Id: Makefile,v 1.3 2003/04/01 02:06:47 max Exp $ # $FreeBSD$ SUBDIR= \ + bcmfw \ bt3cfw \ hccontrol \ + hcsecd \ hcseriald \ l2control \ - l2ping + l2ping \ + rfcomm_pppd .include <bsd.subdir.mk> diff --git a/usr.sbin/bluetooth/bt3cfw/Makefile b/usr.sbin/bluetooth/bt3cfw/Makefile index 05ae1ab721b4..6310c0af7704 100644 --- a/usr.sbin/bluetooth/bt3cfw/Makefile +++ b/usr.sbin/bluetooth/bt3cfw/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1.1.1 2002/11/12 00:39:18 max Exp $ +# $Id: Makefile,v 1.2 2003/03/15 03:06:53 max Exp $ # $FreeBSD$ DESTDIR= /usr/sbin/ @@ -6,7 +6,7 @@ MANDIR= ../share/man/man PROG= bt3cfw MAN8= bt3cfw.8 WARNS?= 2 -CFLAGS+= -g -I../../../sys/netgraph/bluetooth/include +CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include SRCS= bt3cfw.c DPADD= ${LIBNETGRAPH} diff --git a/usr.sbin/bluetooth/bt3cfw/bt3cfw.8 b/usr.sbin/bluetooth/bt3cfw/bt3cfw.8 index dfcfd788182a..9e46b8646830 100644 --- a/usr.sbin/bluetooth/bt3cfw/bt3cfw.8 +++ b/usr.sbin/bluetooth/bt3cfw/bt3cfw.8 @@ -1,6 +1,8 @@ +.\" bt3cfw.8 +.\" .\" 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: @@ -9,7 +11,7 @@ .\" 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 @@ -21,43 +23,44 @@ .\" 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: bt3cfw.8,v 1.3 2003/04/27 19:45:22 max Exp $ .\" $FreeBSD$ -.\" .Dd November 11, 2002 .Dt BT3CFW 8 .Os .Sh NAME -.Nm bt3cfw -.Nd firmware download utility for 3Com Bluetooth PC card driver +.Nm BT3CFW +.Nd Firmware download utility for 3Com Bluetooth PC card driver .Sh SYNOPSIS .Nm -.Op Fl n Ar Netgraph_node_name -.Op Fl f Ar Firmware_file_name +.Op Fl n Ar Netgraph node name +.Op Fl f Ar Firmware file name +.Op Fl h .Sh DESCRIPTION The .Nm -utility connects to the specified Netgraph driver node of type +utility connects to the specified Netgraph driver node of type .Dv BTCCC -and downloads specified firmware file. +and downloads specified firmware file. .Pp Due to copyright issues I will no longer provide firmware with the card -driver. -The firmware can be obtained from the Windows driver package that -can be downloaded from the 3COM web site at no charge. -The firmware name is -.Pa BT3CPCC.BIN . -I am using original firmware that came with the card on CD-ROM. -.Pp -.Dl "MD5 (BT3CPCC.BIN) = 36170fda56ea9fdbf1702c966f8a97f1" +driver. The firmware can be obtained from the Windows driver package that +can be downloaded from the 3COM web site at no charge. The firmware name +is BT3CPCC.BIN. I'm using original firmware that came with the card on CD-ROM. +.Bd -literal -offset indent +MD5 (BT3CPCC.BIN) = 36170fda56ea9fdbf1702c966f8a97f1 +.Ed .Pp The options are as follows: .Bl -tag -width indent -.It Fl n Ar Netgraph_node_name +.It Fl n Ar Netgraph node name Connect to the specified Netgraph driver node of type .Dv BTCCC . -.It Fl f Ar Firmware_file_name +.It Fl f Ar Firmware file name Specify firmware file name for download. +.It Fl h +Display usage message and exit. .El .Sh BUGS Please report if found. diff --git a/usr.sbin/bluetooth/bt3cfw/bt3cfw.c b/usr.sbin/bluetooth/bt3cfw/bt3cfw.c index 09252acf8753..d0a32a81ac0a 100644 --- a/usr.sbin/bluetooth/bt3cfw/bt3cfw.c +++ b/usr.sbin/bluetooth/bt3cfw/bt3cfw.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bt3cfw.c,v 1.1.1.1 2002/11/12 00:39:18 max Exp $ + * $Id: bt3cfw.c,v 1.1 2002/11/24 20:22:37 max Exp $ * $FreeBSD$ */ diff --git a/usr.sbin/bluetooth/hccontrol/Makefile b/usr.sbin/bluetooth/hccontrol/Makefile index c816c3c6d1e0..5b68cd86b240 100644 --- a/usr.sbin/bluetooth/hccontrol/Makefile +++ b/usr.sbin/bluetooth/hccontrol/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.6 2002/09/06 18:52:41 max Exp $ +# $Id: Makefile,v 1.2 2003/03/15 03:07:39 max Exp $ # $FreeBSD$ DESTDIR= /usr/sbin/ @@ -6,7 +6,7 @@ MANDIR= ../share/man/man PROG= hccontrol MAN8= hccontrol.8 WARNS?= 2 -CFLAGS+= -g -I../../../sys/netgraph/bluetooth/include +CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include SRCS= send_recv.c link_policy.c link_control.c \ host_controller_baseband.c info.c status.c node.c hccontrol.c \ util.c diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.8 b/usr.sbin/bluetooth/hccontrol/hccontrol.8 index 88e981328788..c4553db5e54c 100644 --- a/usr.sbin/bluetooth/hccontrol/hccontrol.8 +++ b/usr.sbin/bluetooth/hccontrol/hccontrol.8 @@ -1,6 +1,8 @@ +.\" hccontrol.8 +.\" .\" 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: @@ -9,7 +11,7 @@ .\" 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 @@ -21,9 +23,9 @@ .\" 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: hccontrol.8,v 1.3 2003/04/27 19:45:23 max Exp $ .\" $FreeBSD$ -.\" .Dd June 14, 2002 .Dt HCCONTROL 8 .Os @@ -32,35 +34,34 @@ .Nd HCI configuration utility .Sh SYNOPSIS .Nm -.Op Fl n Ar HCI_node_name -.Op Ar command +.Op Fl n Ar HCI node name +.Op Fl h +.Op Ar command .Op Ar parameters ... .Sh DESCRIPTION The .Nm utility connects to the specified Netgraph node of type -.Dv HCI -and attempts to send specified command to the HCI Netgraph node or to the +.Em HCI +and attempts to send specified command to the HCI Netgraph node or to the associated Bluetooth device. -The .Nm -utility -will print results to the standard output and error messages to +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 n Ar HCI_node_name +.It Fl n Ar HCI node name Connect to the specified HCI Netgraph node. -.It Ar command -One of the supported commands (see below). -Special command -.Cm help -can be used to obtain the list of all supported commands. -To get more +.It Fl h +Display usage message and exit. +.It command +One of the supported commands (see below). Special command +.Dq help +can be used to obtain the list of all supported commands. To get more information about specific command use -.Cm help Ar command . -.It Ar parameters +.Dq help command . +.It parameters One or more optional space separated command parameters. .El .Sh COMMANDS @@ -68,92 +69,92 @@ The currently supported HCI commands in .Nm are: .Pp -.Bl -tag -offset indent -compact -.It Cm Inquiry -.It Cm Create_Connection -.It Cm Disconnect -.It Cm Add_SCO_Connection -.It Cm Change_Connection_Packet_Type -.It Cm Remote_Name_Request -.It Cm Read_Remote_Supported_Features -.It Cm Read_Remote_Version_Information -.It Cm Read_Clock_Offset -.It Cm Role_Discovery -.It Cm Switch_Role -.It Cm Read_Link_Policy_Settings -.It Cm Write_Link_Policy_Settings -.It Cm Reset -.It Cm Read_Pin_Type -.It Cm Write_Pin_Type -.It Cm Read_Stored_Link_Key -.It Cm Write_Stored_Link_Key -.It Cm Delete_Stored_Link_Key -.It Cm Change_Local_Name -.It Cm Read_Local_Name -.It Cm Read_Connection_Accept_Timeout -.It Cm Write_Connection_Accept_Timeout -.It Cm Read_Page_Timeout -.It Cm Write_Page_Timeout -.It Cm Read_Scan_Enable -.It Cm Write_Scan_Enable -.It Cm Read_Page_Scan_Activity -.It Cm Write_Page_Scan_Activity -.It Cm Read_Inquiry_Scan_Activity -.It Cm Write_Inquiry_Scan_Activity -.It Cm Read_Authentication_Enable -.It Cm Write_Authentication_Enable -.It Cm Read_Encryption_Mode -.It Cm Write_Encryption_Mode -.It Cm Read_Class_Of_Device -.It Cm Write_Class_Of_Device -.It Cm Read_Voice_Settings -.It Cm Write_Voice_Settings -.It Cm Read_Number_Broadcast_Retransmissions -.It Cm Write_Number_Broadcast_Retransmissions -.It Cm Read_Hold_Mode_Activity -.It Cm Write_Hold_Mode_Activity -.It Cm Read_SCO_Flow_Control_Enable -.It Cm Write_SCO_Flow_Control_Enable -.It Cm Read_Link_Supervision_Timeout -.It Cm Write_Link_Supervision_Timeout -.It Cm Read_Local_Version_Information -.It Cm Read_Local_Supported_Features -.It Cm Read_Buffer_Size -.It Cm Read_Country_Code -.It Cm Read_BD_ADDR -.It Cm Read_Failed_Contact_Counter -.It Cm Reset_Failed_Contact_Counter -.It Cm Get_Link_Quality -.It Cm Read_RSSI -.El +.Bd -literal -offset indent -compact +Inquiry +Create_Connection +Disconnect +Add_SCO_Connection +Change_Connection_Packet_Type +Remote_Name_Request +Read_Remote_Supported_Features +Read_Remote_Version_Information +Read_Clock_Offset +Role_Discovery +Switch_Role +Read_Link_Policy_Settings +Write_Link_Policy_Settings +Reset +Read_Pin_Type +Write_Pin_Type +Read_Stored_Link_Key +Write_Stored_Link_Key +Delete_Stored_Link_Key +Change_Local_Name +Read_Local_Name +Read_Connection_Accept_Timeout +Write_Connection_Accept_Timeout +Read_Page_Timeout +Write_Page_Timeout +Read_Scan_Enable +Write_Scan_Enable +Read_Page_Scan_Activity +Write_Page_Scan_Activity +Read_Inquiry_Scan_Activity +Write_Inquiry_Scan_Activity +Read_Authentication_Enable +Write_Authentication_Enable +Read_Encryption_Mode +Write_Encryption_Mode +Read_Class_Of_Device +Write_Class_Of_Device +Read_Voice_Settings +Write_Voice_Settings +Read_Number_Broadcast_Retransmissions +Write_Number_Broadcast_Retransmissions +Read_Hold_Mode_Activity +Write_Hold_Mode_Activity +Read_SCO_Flow_Control_Enable +Write_SCO_Flow_Control_Enable +Read_Link_Supervision_Timeout +Write_Link_Supervision_Timeout +Read_Local_Version_Information +Read_Local_Supported_Features +Read_Buffer_Size +Read_Country_Code +Read_BD_ADDR +Read_Failed_Contact_Counter +Reset_Failed_Contact_Counter +Get_Link_Quality +Read_RSSI +.Ed .Pp The currently supported node commands in .Nm are: .Pp -.Bl -tag -offset indent -compact -.It Cm Read_Node_State -.It Cm Initialize -.It Cm Read_Debug_Level -.It Cm Write_Debug_Level -.It Cm Read_Command_Timeout -.It Cm Write_Command_Timeout -.It Cm Read_Node_Buffer_Size -.It Cm Read_Node_BD_ADDR -.It Cm Read_Node_Features -.It Cm Read_Node_Stat -.It Cm Reset_Node_Stat -.It Cm Flush_Neighbor_Cache -.It Cm Read_Neighbor_Cache -.It Cm Read_Connection_List -.It Cm Read_Node_Link_Policy_Settings_Mask -.It Cm Write_Node_Link_Policy_Settings_Mask -.It Cm Read_Node_Packet_Mask -.It Cm Write_Node_Packet_Mask -.El +.Bd -literal -offset indent -compact +Read_Node_State +Initialize +Read_Debug_Level +Write_Debug_Level +Read_Node_Buffer_Size +Read_Node_BD_ADDR +Read_Node_Features +Read_Node_Stat +Reset_Node_Stat +Flush_Neighbor_Cache +Read_Neighbor_Cache +Read_Connection_List +Read_Node_Link_Policy_Settings_Mask +Write_Node_Link_Policy_Settings_Mask +Read_Node_Packet_Mask +Write_Node_Packet_Mask +Read_Node_Role_Switch +Write_Node_Role_Switch +.Ed +.Pp .Sh BUGS -Most likely. -Please report if found. +Most likely. Please report if found. .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.c b/usr.sbin/bluetooth/hccontrol/hccontrol.c index 12b70eb07d8e..fafbf7ba7ab1 100644 --- a/usr.sbin/bluetooth/hccontrol/hccontrol.c +++ b/usr.sbin/bluetooth/hccontrol/hccontrol.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: hccontrol.c,v 1.11 2002/09/12 18:19:43 max Exp $ + * $Id: hccontrol.c,v 1.2 2003/04/27 19:45:24 max Exp $ * $FreeBSD$ */ @@ -63,7 +63,7 @@ main(int argc, char *argv[]) int n; /* Process command line arguments */ - while ((n = getopt(argc, argv, "n:v")) != -1) { + while ((n = getopt(argc, argv, "n:vh")) != -1) { switch (n) { case 'n': node = optarg; @@ -73,7 +73,7 @@ main(int argc, char *argv[]) verbose = 1; break; - case '?': + case 'h': default: usage(); } @@ -268,7 +268,7 @@ print_hci_command(struct hci_command *category) static void usage(void) { - fprintf(stdout, "Usage: hccontrol -n HCI_node_name cmd [p1] [..]]\n"); + fprintf(stdout, "Usage: hccontrol -n HCI_node_name [-h] cmd [p1] [..]]\n"); exit(255); } /* usage */ diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.h b/usr.sbin/bluetooth/hccontrol/hccontrol.h index 8bcf7647397d..d578feade1d5 100644 --- a/usr.sbin/bluetooth/hccontrol/hccontrol.h +++ b/usr.sbin/bluetooth/hccontrol/hccontrol.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: hccontrol.h,v 1.8 2002/09/12 18:19:43 max Exp $ + * $Id: hccontrol.h,v 1.1 2002/11/24 20:22:38 max Exp $ * $FreeBSD$ */ diff --git a/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c b/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c index 3aa157169382..5854b00666ed 100644 --- a/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c +++ b/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: host_controller_baseband.c,v 1.12 2002/11/19 18:34:06 max Exp $ + * $Id: host_controller_baseband.c,v 1.1 2002/11/24 20:22:38 max Exp $ * $FreeBSD$ */ diff --git a/usr.sbin/bluetooth/hccontrol/info.c b/usr.sbin/bluetooth/hccontrol/info.c index 447a4930b012..1a8649fd794e 100644 --- a/usr.sbin/bluetooth/hccontrol/info.c +++ b/usr.sbin/bluetooth/hccontrol/info.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: info.c,v 1.7 2002/09/06 18:52:41 max Exp $ + * $Id: info.c,v 1.1 2002/11/24 20:22:38 max Exp $ * $FreeBSD$ */ diff --git a/usr.sbin/bluetooth/hccontrol/link_control.c b/usr.sbin/bluetooth/hccontrol/link_control.c index 68bf35f2a6dd..2f3b4b2d2d40 100644 --- a/usr.sbin/bluetooth/hccontrol/link_control.c +++ b/usr.sbin/bluetooth/hccontrol/link_control.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: link_control.c,v 1.12 2002/09/17 16:36:46 max Exp $ + * $Id: link_control.c,v 1.2 2003/03/15 03:07:39 max Exp $ * $FreeBSD$ */ @@ -536,39 +536,46 @@ hci_remote_name_request(int s, int argc, char **argv) ng_hci_remote_name_req_cp cp; ng_hci_event_pkt_t *e = (ng_hci_event_pkt_t *) b; + memset(&cp, 0, sizeof(cp)); + cp.page_scan_rep_mode = NG_HCI_SCAN_REP_MODE0; + cp.page_scan_mode = NG_HCI_MANDATORY_PAGE_SCAN_MODE; + /* parse command parameters */ switch (argc) { case 4: - /* BD_ADDR */ - if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x", - &n5, &n4, &n3, &n2, &n1, &n0) != 6) - return (USAGE); - - cp.bdaddr.b[0] = (n0 & 0xff); - cp.bdaddr.b[1] = (n1 & 0xff); - cp.bdaddr.b[2] = (n2 & 0xff); - cp.bdaddr.b[3] = (n3 & 0xff); - cp.bdaddr.b[4] = (n4 & 0xff); - cp.bdaddr.b[5] = (n5 & 0xff); - - /* page_scan_rep_mode */ - if (sscanf(argv[1], "%d", &n0) != 1 || n0 < 0x00 || n0 > 0x02) + /* clock_offset */ + if (sscanf(argv[3], "%x", &n0) != 1) return (USAGE); - cp.page_scan_rep_mode = (n0 & 0xff); + cp.clock_offset = (n0 & 0xffff); + cp.clock_offset = htole16(cp.clock_offset); + case 3: /* page_scan_mode */ if (sscanf(argv[2], "%d", &n0) != 1 || n0 < 0x00 || n0 > 0x03) return (USAGE); cp.page_scan_mode = (n0 & 0xff); - /* clock_offset */ - if (sscanf(argv[3], "%x", &n0) != 1) + case 2: + /* page_scan_rep_mode */ + if (sscanf(argv[1], "%d", &n0) != 1 || n0 < 0x00 || n0 > 0x02) return (USAGE); - cp.clock_offset = (n0 & 0xffff); - cp.clock_offset = htole16(cp.clock_offset); + cp.page_scan_rep_mode = (n0 & 0xff); + + case 1: + /* BD_ADDR */ + if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x", + &n5, &n4, &n3, &n2, &n1, &n0) != 6) + return (USAGE); + + cp.bdaddr.b[0] = (n0 & 0xff); + cp.bdaddr.b[1] = (n1 & 0xff); + cp.bdaddr.b[2] = (n2 & 0xff); + cp.bdaddr.b[3] = (n3 & 0xff); + cp.bdaddr.b[4] = (n4 & 0xff); + cp.bdaddr.b[5] = (n5 & 0xff); break; default: diff --git a/usr.sbin/bluetooth/hccontrol/link_policy.c b/usr.sbin/bluetooth/hccontrol/link_policy.c index dec9259dc8ec..0a40f56ffe3a 100644 --- a/usr.sbin/bluetooth/hccontrol/link_policy.c +++ b/usr.sbin/bluetooth/hccontrol/link_policy.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: link_policy.c,v 1.3 2002/09/17 16:33:44 max Exp $ + * $Id: link_policy.c,v 1.1 2002/11/24 20:22:38 max Exp $ * $FreeBSD$ */ diff --git a/usr.sbin/bluetooth/hccontrol/node.c b/usr.sbin/bluetooth/hccontrol/node.c index b7ff33ac07c4..477102761ded 100644 --- a/usr.sbin/bluetooth/hccontrol/node.c +++ b/usr.sbin/bluetooth/hccontrol/node.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: node.c,v 1.8 2002/11/12 22:33:17 max Exp $ + * $Id: node.c,v 1.4 2003/03/23 21:28:17 max Exp $ * $FreeBSD$ */ @@ -52,7 +52,7 @@ hci_read_node_state(int s, int argc, char **argv) if (ioctl(s, SIOC_HCI_RAW_NODE_GET_STATE, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "Node: %s\nState: %#x\n", r.hci_node, r.state); + fprintf(stdout, "State: %#x\n", r.state); return (OK); } /* hci_read_node_state */ @@ -61,10 +61,7 @@ hci_read_node_state(int s, int argc, char **argv) static int hci_node_initialize(int s, int argc, char **argv) { - struct ng_btsocket_hci_raw_node_init r; - - memset(&r, 0, sizeof(r)); - if (ioctl(s, SIOC_HCI_RAW_NODE_INIT, &r, sizeof(r)) < 0) + if (ioctl(s, SIOC_HCI_RAW_NODE_INIT) < 0) return (ERROR); return (OK); @@ -80,7 +77,7 @@ hci_read_debug_level(int s, int argc, char **argv) if (ioctl(s, SIOC_HCI_RAW_NODE_GET_DEBUG, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "Node: %s\nDebug level: %d\n", r.hci_node, r.debug); + fprintf(stdout, "Debug level: %d\n", r.debug); return (OK); } /* hci_read_debug_level */ @@ -117,8 +114,6 @@ hci_read_node_buffer_size(int s, int argc, char **argv) if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BUFFER, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "Node: %s\n", - r.hci_node); fprintf(stdout, "Number of free command buffers: %d\n", r.buffer.cmd_free); fprintf(stdout, "Max. ACL packet size: %d\n", @@ -147,7 +142,6 @@ hci_read_node_bd_addr(int s, int argc, char **argv) if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BDADDR, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "Node: %s\n", r.hci_node); fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", r.bdaddr.b[5], r.bdaddr.b[4], r.bdaddr.b[3], r.bdaddr.b[2], r.bdaddr.b[1], r.bdaddr.b[0]); @@ -167,7 +161,7 @@ hci_read_node_features(int s, int argc, char **argv) if (ioctl(s, SIOC_HCI_RAW_NODE_GET_FEATURES, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "Node: %s\nFeatures: ", r.hci_node); + fprintf(stdout, "Features: "); for (n = 0; n < sizeof(r.features)/sizeof(r.features[0]); n++) fprintf(stdout, "%#02x ", r.features[n]); fprintf(stdout, "\n%s\n", hci_features2str(r.features, @@ -186,7 +180,6 @@ hci_read_node_stat(int s, int argc, char **argv) if (ioctl(s, SIOC_HCI_RAW_NODE_GET_STAT, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "Node: %s\n", r.hci_node); fprintf(stdout, "Commands sent: %d\n", r.stat.cmd_sent); fprintf(stdout, "Events received: %d\n", r.stat.evnt_recv); fprintf(stdout, "ACL packets received: %d\n", r.stat.acl_recv); @@ -203,10 +196,7 @@ hci_read_node_stat(int s, int argc, char **argv) static int hci_reset_node_stat(int s, int argc, char **argv) { - struct ng_btsocket_hci_raw_node_reset_stat r; - - memset(&r, 0, sizeof(r)); - if (ioctl(s, SIOC_HCI_RAW_NODE_RESET_STAT, &r, sizeof(r)) < 0) + if (ioctl(s, SIOC_HCI_RAW_NODE_RESET_STAT) < 0) return (ERROR); return (OK); @@ -216,11 +206,7 @@ hci_reset_node_stat(int s, int argc, char **argv) static int hci_flush_neighbor_cache(int s, int argc, char **argv) { - struct ng_btsocket_hci_raw_node_flush_neighbor_cache r; - - memset(&r, 0, sizeof(r)); - if (ioctl(s, SIOC_HCI_RAW_NODE_FLUSH_NEIGHBOR_CACHE, - &r, sizeof(r)) < 0) + if (ioctl(s, SIOC_HCI_RAW_NODE_FLUSH_NEIGHBOR_CACHE) < 0) return (ERROR); return (OK); @@ -248,7 +234,6 @@ hci_read_neighbor_cache(int s, int argc, char **argv) goto out; } - fprintf(stdout, "Neighbor cache for the node: %s\n", r.hci_node); fprintf(stdout, "BD_ADDR " \ "Features " \ @@ -299,7 +284,6 @@ hci_read_connection_list(int s, int argc, char **argv) goto out; } - fprintf(stdout, "Connections list for the node: %s\n", r.hci_node); fprintf(stdout, "Remote BD_ADDR " \ "Handle " \ @@ -345,9 +329,9 @@ out: return (error); } /* hci_read_connection_list */ -/* Send Read_Link_Policy_Settings_Mask command to the node */ +/* Send Read_Node_Link_Policy_Settings_Mask command to the node */ int -hci_read_link_policy_settings_mask(int s, int argc, char **argv) +hci_read_node_link_policy_settings_mask(int s, int argc, char **argv) { struct ng_btsocket_hci_raw_node_link_policy_mask r; @@ -355,15 +339,14 @@ hci_read_link_policy_settings_mask(int s, int argc, char **argv) if (ioctl(s, SIOC_HCI_RAW_NODE_GET_LINK_POLICY_MASK, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "Node: %s\nLink Policy Settings mask: %#04x\n", - r.hci_node, r.policy_mask); + fprintf(stdout, "Link Policy Settings mask: %#04x\n", r.policy_mask); return (OK); -} /* hci_read_link_policy_settings_mask */ +} /* hci_read_node_link_policy_settings_mask */ -/* Send Write_Link_Policy_Settings_Mask command to the node */ +/* Send Write_Node_Link_Policy_Settings_Mask command to the node */ int -hci_write_link_policy_settings_mask(int s, int argc, char **argv) +hci_write_node_link_policy_settings_mask(int s, int argc, char **argv) { struct ng_btsocket_hci_raw_node_link_policy_mask r; int m; @@ -386,11 +369,11 @@ hci_write_link_policy_settings_mask(int s, int argc, char **argv) return (ERROR); return (OK); -} /* hci_write_link_policy_settings_mask */ +} /* hci_write_node_link_policy_settings_mask */ -/* Send Read_Packet_Mask command to the node */ +/* Send Read_Node_Packet_Mask command to the node */ int -hci_read_packet_mask(int s, int argc, char **argv) +hci_read_node_packet_mask(int s, int argc, char **argv) { struct ng_btsocket_hci_raw_node_packet_mask r; @@ -398,15 +381,14 @@ hci_read_packet_mask(int s, int argc, char **argv) if (ioctl(s, SIOC_HCI_RAW_NODE_GET_PACKET_MASK, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "Node: %s\nPacket mask: %#04x\n", - r.hci_node, r.packet_mask); + fprintf(stdout, "Packet mask: %#04x\n", r.packet_mask); return (OK); -} /* hci_read_packet_mask */ +} /* hci_read_node_packet_mask */ -/* Send Write_Packet_Mask command to the node */ +/* Send Write_Node_Packet_Mask command to the node */ int -hci_write_packet_mask(int s, int argc, char **argv) +hci_write_node_packet_mask(int s, int argc, char **argv) { struct ng_btsocket_hci_raw_node_packet_mask r; int m; @@ -429,88 +411,175 @@ hci_write_packet_mask(int s, int argc, char **argv) return (ERROR); return (OK); -} /* hci_write_packet_mask */ +} /* hci_write_node_packet_mask */ + +/* Send Read_Node_Role_Switch command to the node */ +int +hci_read_node_role_switch(int s, int argc, char **argv) +{ + struct ng_btsocket_hci_raw_node_role_switch r; + + memset(&r, 0, sizeof(r)); + if (ioctl(s, SIOC_HCI_RAW_NODE_GET_ROLE_SWITCH, &r, sizeof(r)) < 0) + return (ERROR); + + fprintf(stdout, "Role switch: %d\n", r.role_switch); + + return (OK); +} /* hci_read_node_role_switch */ + +/* Send Write_Node_Role_Switch command to the node */ +int +hci_write_node_role_switch(int s, int argc, char **argv) +{ + struct ng_btsocket_hci_raw_node_role_switch r; + int m; + + memset(&r, 0, sizeof(r)); + + switch (argc) { + case 1: + if (sscanf(argv[0], "%d", &m) != 1) + return (USAGE); + + r.role_switch = m? 1 : 0; + break; + + default: + return (USAGE); + } + + if (ioctl(s, SIOC_HCI_RAW_NODE_SET_ROLE_SWITCH, &r, sizeof(r)) < 0) + return (ERROR); + + return (OK); +} /* hci_write_node_role_switch */ struct hci_command node_commands[] = { { "read_node_state", -"Get HCI node state", +"Get the HCI node state", &hci_read_node_state }, { "initialize", -"Initialize HCI node", +"Initialize the HCI node", &hci_node_initialize }, { "read_debug_level", -"Read HCI node debug level", +"Read the HCI node debug level", &hci_read_debug_level }, { "write_debug_level <level>", -"Write HCI node debug level", +"Write the HCI node debug level", &hci_write_debug_level }, { "read_node_buffer_size", -"Read HCI node buffer information", +"Read the HCI node buffer information. This will return current state of the\n"\ +"HCI buffer for the HCI node", &hci_read_node_buffer_size }, { "read_node_bd_addr", -"Read HCI node BD_ADDR", +"Read the HCI node BD_ADDR. Returns device BD_ADDR as cached by the HCI node", &hci_read_node_bd_addr }, { "read_node_features", -"Read HCI node features", +"Read the HCI node features. This will return list of supported features as\n" \ +"cached by the HCI node", &hci_read_node_features }, { "read_node_stat", -"Read HCI node statistic information", +"Read packets and bytes counters for the HCI node", &hci_read_node_stat }, { "reset_node_stat", -"Reset HCI node statistic information", +"Reset packets and bytes counters for the HCI node", &hci_reset_node_stat }, { "flush_neighbor_cache", -"Flush HCI node neighbor cache", +"Flush content of the HCI node neighbor cache", &hci_flush_neighbor_cache }, { "read_neighbor_cache", -"Read HCI node neighbor cache", +"Read content of the HCI node neighbor cache", &hci_read_neighbor_cache }, { "read_connection_list", -"Read connection list", +"Read the baseband connection descriptors list for the HCI node", &hci_read_connection_list }, { "read_node_link_policy_settings_mask", -"Read Link Policy Settinngs mask for the node", -&hci_read_link_policy_settings_mask +"Read the value of the Link Policy Settinngs mask for the HCI node", +&hci_read_node_link_policy_settings_mask }, { "write_node_link_policy_settings_mask <policy_mask>", -"Write Link Policy Settinngs mask for the node. Policy mask - xxxx", -&hci_write_link_policy_settings_mask +"Write the value of the Link Policy Settings mask for the HCI node. By default\n" \ +"all supported Link Policy modes (as reported by the local device features) are\n"\ +"enabled. The particular Link Policy mode is enabled if local device supports\n"\ +"it and correspinding bit in the mask was set\n\n" \ +"\t<policy_mask> - xxxx; Link Policy mask\n" \ +"\t\t0x0000 - Disable All LM Modes\n" \ +"\t\t0x0001 - Enable Master Slave Switch\n" \ +"\t\t0x0002 - Enable Hold Mode\n" \ +"\t\t0x0004 - Enable Sniff Mode\n" \ +"\t\t0x0008 - Enable Park Mode\n", +&hci_write_node_link_policy_settings_mask }, { "read_node_packet_mask", -"Read Packet mask for the node", -&hci_read_packet_mask +"Read the value of the Packet mask for the HCI node", +&hci_read_node_packet_mask }, { "write_node_packet_mask <packet_mask>", -"Write Packet mask for the node. Packet mask - xxxx", -&hci_write_packet_mask +"Write the value of the Packet mask for the HCI node. By default all supported\n" \ +"packet types (as reported by the local device features) are enabled. The\n" \ +"particular packet type is enabled if local device supports it and corresponding\n" \ +"bit in the mask was set\n\n" \ +"\t<packet_mask> - xxxx; packet type mask\n" \ +"" \ +"\t\tACL packets\n" \ +"\t\t-----------\n" \ +"\t\t0x0008 DM1\n" \ +"\t\t0x0010 DH1\n" \ +"\t\t0x0400 DM3\n" \ +"\t\t0x0800 DH3\n" \ +"\t\t0x4000 DM5\n" \ +"\t\t0x8000 DH5\n" \ +"\n" \ +"\t\tSCO packets\n" \ +"\t\t-----------\n" \ +"\t\t0x0020 HV1\n" \ +"\t\t0x0040 HV2\n" \ +"\t\t0x0080 HV3\n", +&hci_write_node_packet_mask +}, +{ +"read_node_role_switch", +"Read the value of the Role Switch parameter for the HCI node", +&hci_read_node_role_switch +}, +{ +"write_node_role_switch {0|1}", +"Write the value of the Role Switch parameter for the HCI node. By default,\n" \ +"if Role Switch is supported, local device will try to perform Role Switch\n" \ +"and become Master on incoming connection. Some devices do not support Role\n" \ +"Switch and thus incomming connections from such devices will fail. Setting\n" \ +"this parameter to zero will prevent Role Switch and thus accepting device\n" \ +"will remain Slave", +&hci_write_node_role_switch }, { NULL, diff --git a/usr.sbin/bluetooth/hccontrol/send_recv.c b/usr.sbin/bluetooth/hccontrol/send_recv.c index aff6f9341c69..43a2e2adf29b 100644 --- a/usr.sbin/bluetooth/hccontrol/send_recv.c +++ b/usr.sbin/bluetooth/hccontrol/send_recv.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: send_recv.c,v 1.4 2002/09/04 21:31:30 max Exp $ + * $Id: send_recv.c,v 1.1 2002/11/24 20:22:38 max Exp $ * $FreeBSD$ */ diff --git a/usr.sbin/bluetooth/hccontrol/status.c b/usr.sbin/bluetooth/hccontrol/status.c index 0494aa74a8b4..fdbf61fd29d9 100644 --- a/usr.sbin/bluetooth/hccontrol/status.c +++ b/usr.sbin/bluetooth/hccontrol/status.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: status.c,v 1.2 2002/09/06 18:52:41 max Exp $ + * $Id: status.c,v 1.1 2002/11/24 20:22:38 max Exp $ * $FreeBSD$ */ @@ -231,7 +231,7 @@ struct hci_command status_commands[] = { "read_rssi <connection_handle>", "\nThis command will read the value for the difference between the\n" \ "measured Received Signal Strength Indication (RSSI) and the limits of\n" \ -"the Golden Receive Power Range for an ACL connection handle to another\n" \ +"the Golden Receive Power Range for a ACL connection handle to another\n" \ "Bluetooth device. Any positive RSSI value returned by the Host Controller\n" \ "indicates how many dB the RSSI is above the upper limit, any negative\n" \ "value indicates how many dB the RSSI is below the lower limit. The value\n" \ diff --git a/usr.sbin/bluetooth/hccontrol/util.c b/usr.sbin/bluetooth/hccontrol/util.c index 51868b4c7698..7abe4d42a60f 100644 --- a/usr.sbin/bluetooth/hccontrol/util.c +++ b/usr.sbin/bluetooth/hccontrol/util.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: util.c,v 1.2 2002/09/12 18:19:43 max Exp $ + * $Id: util.c,v 1.1 2002/11/24 20:22:38 max Exp $ * $FreeBSD$ */ diff --git a/usr.sbin/bluetooth/hcsecd/Makefile b/usr.sbin/bluetooth/hcsecd/Makefile new file mode 100644 index 000000000000..886010bb117d --- /dev/null +++ b/usr.sbin/bluetooth/hcsecd/Makefile @@ -0,0 +1,12 @@ +# $Id: Makefile,v 1.2 2003/03/15 03:07:42 max Exp $ +# $FreeBSD$ + +DESTDIR= /usr/sbin/ +MANDIR= ../share/man/man +PROG= hcsecd +MAN8= hcsecd.8 +WARNS?= 1 +CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include +SRCS= hcsecd.c lexer.l parser.y + +.include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.8 b/usr.sbin/bluetooth/hcsecd/hcsecd.8 new file mode 100644 index 000000000000..880ee1c2ac84 --- /dev/null +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.8 @@ -0,0 +1,101 @@ +.\" hcsecd.8 +.\" +.\" 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: hcsecd.8,v 1.3 2003/04/27 19:45:32 max Exp $ +.\" $FreeBSD$ +.Dd November 16, 2002 +.Dt HCSECD 8 +.Os +.Sh NAME +.Nm hcsecd +.Nd control link keys and PIN codes for Bluetooth devices +.Sh SYNOPSIS +.Nm +.Op Fl f Ar configfile +.Op Fl d +.Op Fl h +.Sh DESCRIPTION +The +.Nm +daemon controls link keys and PIN code for Bluetooth devices. It opens raw +HCI socket and listens for the +.Dv Link_Key_Request +and +.Dv PIN_Code_Request +HCI events. Once appropriate HCI event has been received, the daemon will +scan configuration file for matching entry. The remove device BD_ADDR is used +as a key. If no matching entry was found then the default entry will be used. +If no default entry was found than it is assumed no link key and no PIN code +exist. For any given entry link key takes precedence over PIN code. If link key +was not specified then it means device must generate link key from PIN code. If +entry was found and has the link key (or PIN code) then +the +.Dv Link_Key_Request_Reply +(or +.Dv PIN_Code_Request_Reply +) command will be sent back to the device. Otherwise the +.Dv Link_Key_Request_Negative_Reply +(or +.Dv PIN_Code_Request_Negative_Reply +) command will be sent back to the device. +.Pp +The +.Nm +daemon currently does not handle HCI +.Dv Link_Key_Notification +event and does not cache link keys created from the PIN codes. It means +that the link key only exists while connection is opened. After the connection +has been terminated the user will have to enter PIN code again. +.Pp +The command line options are as follows: +.Bl -tag -width Ds +.It Fl f Ar filename +Name of configuration file. Default is +.Pa /usr/local/etc/hcsecd.conf . +.It Fl d +Do not detach from the controlling terminal. +.It Fl h +Display usage message and exit. +.El +.Sh BUGS +Currently there is no way to select link key or PIN code based on which local +device received the request. Everything is based on remote device BD_ADDR. +Also might implement interface for external helpers to obtain link keys and +PIN codes. +.Sh FILES +.Bl -tag -width /etc/usbd.conf -compact +.It Pa /usr/local/etc/hcsecd.conf +.It Pa /var/run/hcsecd.pid +.El +.Sh SEE ALSO +.Xr netgraph 3 , +.Xr netgraph 4 , +.Xr ng_hci 4 , +.Xr ng_btsocket 4 , +.Xr hccontrol 8 , +.Xr hcseriald 8 +.Sh AUTHORS +.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.c b/usr.sbin/bluetooth/hcsecd/hcsecd.c new file mode 100644 index 000000000000..0f72eb7ba895 --- /dev/null +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.c @@ -0,0 +1,422 @@ +/* + * hcsecd.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: hcsecd.c,v 1.3 2003/04/27 19:45:32 max Exp $ + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/endian.h> +#include <sys/socket.h> +#include <sys/queue.h> +#include <bitstring.h> +#include <err.h> +#include <errno.h> +#include <ng_hci.h> +#include <ng_l2cap.h> +#include <ng_btsocket.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include "hcsecd.h" + +#define HCSECD_BUFFER_SIZE 512 +#define HCSECD_IDENT "hcsecd" +#define HCSECD_PIDFILE "/var/run/" HCSECD_IDENT ".pid" + +static int done = 0; + +static int process_pin_code_request_event + (int sock, struct sockaddr_hci *addr, bdaddr_p bdaddr); +static int process_link_key_request_event + (int sock, struct sockaddr_hci *addr, bdaddr_p bdaddr); +static int send_pin_code_reply + (int sock, struct sockaddr_hci *addr, bdaddr_p bdaddr, char const *pin); +static int send_link_key_reply + (int sock, struct sockaddr_hci *addr, bdaddr_p bdaddr, u_int8_t *key); +static void sigint + (int s); +static void usage + (void); + +/* Main */ +int +main(int argc, char *argv[]) +{ + int n, detach, sock, size; + struct sigaction sa; + struct sockaddr_hci addr; + struct ng_btsocket_hci_raw_filter filter; + char buffer[HCSECD_BUFFER_SIZE]; + ng_hci_event_pkt_t *event = NULL; + + detach = 1; + + while ((n = getopt(argc, argv, "df:h")) != -1) { + switch (n) { + case 'd': + detach = 0; + break; + + case 'f': + config_file = optarg; + break; + + case 'h': + default: + usage(); + /* NOT REACHED */ + } + } + + if (config_file == NULL) + usage(); + /* NOT REACHED */ + + if (getuid() != 0) + errx(1, "** ERROR: You should run %s as privileged user!", + HCSECD_IDENT); + + /* Set signal handlers */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sigint; + sa.sa_flags = SA_NOCLDWAIT; + if (sigaction(SIGINT, &sa, NULL) < 0) + err(1, "Could not sigaction(SIGINT)"); + if (sigaction(SIGTERM, &sa, NULL) < 0) + err(1, "Could not sigaction(SIGINT)"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = read_config_file; + if (sigaction(SIGHUP, &sa, NULL) < 0) + err(1, "Could not sigaction(SIGHUP)"); + + /* Open socket and set filter */ + sock = socket(PF_BLUETOOTH, SOCK_RAW, BLUETOOTH_PROTO_HCI); + if (sock < 0) + err(1, "Could not create HCI socket"); + + memset(&filter, 0, sizeof(filter)); + bit_set(filter.event_mask, NG_HCI_EVENT_PIN_CODE_REQ - 1); + bit_set(filter.event_mask, NG_HCI_EVENT_LINK_KEY_REQ - 1); + + if (setsockopt(sock, SOL_HCI_RAW, SO_HCI_RAW_FILTER, + (void * const) &filter, sizeof(filter)) < 0) + err(1, "Could not set HCI socket filter"); + + if (detach) + if (daemon(0, 0) < 0) + err(1, "Could not daemon()ize"); + + openlog(HCSECD_IDENT, LOG_NDELAY|LOG_PERROR|LOG_PID, LOG_DAEMON); + + read_config_file(0); + + if (detach) { + FILE *pid = NULL; + + if ((pid = fopen(HCSECD_PIDFILE, "w")) == NULL) { + syslog(LOG_ERR, "Could not create PID file %s. %s (%d)", + HCSECD_PIDFILE, strerror(errno), errno); + exit(1); + } + + fprintf(pid, "%d", getpid()); + fclose(pid); + } + + event = (ng_hci_event_pkt_t *) buffer; + while (!done) { + size = sizeof(addr); + n = recvfrom(sock, buffer, sizeof(buffer), 0, + (struct sockaddr *) &addr, &size); + if (n < 0) { + if (errno == EINTR) + continue; + + syslog(LOG_ERR, "Could not receive from HCI socket. " \ + "%s (%d)", strerror(errno), errno); + exit(1); + } + + if (event->type != NG_HCI_EVENT_PKT) { + syslog(LOG_ERR, "Received unexpected HCI packet, " \ + "type=%#x", event->type); + continue; + } + + switch (event->event) { + case NG_HCI_EVENT_PIN_CODE_REQ: + process_pin_code_request_event(sock, &addr, + (bdaddr_p)(event + 1)); + break; + + case NG_HCI_EVENT_LINK_KEY_REQ: + process_link_key_request_event(sock, &addr, + (bdaddr_p)(event + 1)); + break; + + default: + syslog(LOG_ERR, "Received unexpected HCI event, " \ + "event=%#x", event->event); + break; + } + } + + if (detach) + if (remove(HCSECD_PIDFILE) < 0) + syslog(LOG_ERR, "Could not remove PID file %s. %s (%d)", + HCSECD_PIDFILE, strerror(errno), errno); + + clean_config(); + closelog(); + close(sock); + + return (0); +} + +/* Process PIN_Code_Request event */ +static int +process_pin_code_request_event(int sock, struct sockaddr_hci *addr, + bdaddr_p bdaddr) +{ + link_key_p key = NULL; + + syslog(LOG_DEBUG, "Got PIN_Code_Request event from '%s', " \ + "remote bdaddr %x:%x:%x:%x:%x:%x", addr->hci_node, + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + + if ((key = get_key(bdaddr, 0)) != NULL) { + syslog(LOG_DEBUG, "Found matching entry, " \ + "remote bdaddr %x:%x:%x:%x:%x:%x, name '%s', " \ + "PIN code %s", + key->bdaddr.b[5], key->bdaddr.b[4], + key->bdaddr.b[3], key->bdaddr.b[2], + key->bdaddr.b[1], key->bdaddr.b[0], + (key->name != NULL)? key->name : "No name", + (key->pin != NULL)? "exists" : "doesn't exist"); + + return (send_pin_code_reply(sock, addr, bdaddr, key->pin)); + } + + syslog(LOG_DEBUG, "Could not PIN code for remote bdaddr " \ + "%x:%x:%x:%x:%x:%x", + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + + return (send_pin_code_reply(sock, addr, bdaddr, NULL)); +} + +/* Process Link_Key_Request event */ +static int +process_link_key_request_event(int sock, struct sockaddr_hci *addr, + bdaddr_p bdaddr) +{ + link_key_p key = NULL; + + syslog(LOG_DEBUG, "Got Link_Key_Request event from '%s', " \ + "remote bdaddr %x:%x:%x:%x:%x:%x", addr->hci_node, + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + + if ((key = get_key(bdaddr, 0)) != NULL) { + syslog(LOG_DEBUG, "Found matching entry, " \ + "remote bdaddr %x:%x:%x:%x:%x:%x, name '%s', " \ + "link key %s", + key->bdaddr.b[5], key->bdaddr.b[4], + key->bdaddr.b[3], key->bdaddr.b[2], + key->bdaddr.b[1], key->bdaddr.b[0], + (key->name != NULL)? key->name : "No name", + (key->key != NULL)? "exists" : "doesn't exist"); + + return (send_link_key_reply(sock, addr, bdaddr, key->key)); + } + + syslog(LOG_DEBUG, "Could not find link key for remote bdaddr " \ + "%x:%x:%x:%x:%x:%x", + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + + return (send_link_key_reply(sock, addr, bdaddr, NULL)); +} + +/* Send PIN_Code_[Negative]_Reply */ +static int +send_pin_code_reply(int sock, struct sockaddr_hci *addr, + bdaddr_p bdaddr, char const *pin) +{ + u_int8_t buffer[HCSECD_BUFFER_SIZE]; + ng_hci_cmd_pkt_t *cmd = NULL; + + memset(buffer, 0, sizeof(buffer)); + + cmd = (ng_hci_cmd_pkt_t *) buffer; + cmd->type = NG_HCI_CMD_PKT; + + if (pin != NULL) { + ng_hci_pin_code_rep_cp *cp = NULL; + + cmd->opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL, + NG_HCI_OCF_PIN_CODE_REP)); + cmd->length = sizeof(*cp); + + cp = (ng_hci_pin_code_rep_cp *)(cmd + 1); + memcpy(&cp->bdaddr, bdaddr, sizeof(cp->bdaddr)); + strncpy(cp->pin, pin, sizeof(cp->pin)); + cp->pin_size = strlen(cp->pin); + + syslog(LOG_DEBUG, "Sending PIN_Code_Reply to '%s' " \ + "for remote bdaddr %x:%x:%x:%x:%x:%x", + addr->hci_node, + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + } else { + ng_hci_pin_code_neg_rep_cp *cp = NULL; + + cmd->opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL, + NG_HCI_OCF_PIN_CODE_NEG_REP)); + cmd->length = sizeof(*cp); + + cp = (ng_hci_pin_code_neg_rep_cp *)(cmd + 1); + memcpy(&cp->bdaddr, bdaddr, sizeof(cp->bdaddr)); + + syslog(LOG_DEBUG, "Sending PIN_Code_Negative_Reply to '%s' " \ + "for remote bdaddr %x:%x:%x:%x:%x:%x", + addr->hci_node, + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + } + +again: + if (sendto(sock, buffer, sizeof(*cmd) + cmd->length, 0, + (struct sockaddr *) addr, sizeof(*addr)) < 0) { + if (errno == EINTR) + goto again; + + syslog(LOG_ERR, "Could not send PIN code reply to '%s' " \ + "for remote bdaddr %x:%x:%x:%x:%x:%x. %s (%d)", + addr->hci_node, + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0], + strerror(errno), errno); + return (-1); + } + + return (0); +} + +/* Send Link_Key_[Negative]_Reply */ +static int +send_link_key_reply(int sock, struct sockaddr_hci *addr, + bdaddr_p bdaddr, u_int8_t *key) +{ + u_int8_t buffer[HCSECD_BUFFER_SIZE]; + ng_hci_cmd_pkt_t *cmd = NULL; + + memset(buffer, 0, sizeof(buffer)); + + cmd = (ng_hci_cmd_pkt_t *) buffer; + cmd->type = NG_HCI_CMD_PKT; + + if (key != NULL) { + ng_hci_link_key_rep_cp *cp = NULL; + + cmd->opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL, + NG_HCI_OCF_LINK_KEY_REP)); + cmd->length = sizeof(*cp); + + cp = (ng_hci_link_key_rep_cp *)(cmd + 1); + memcpy(&cp->bdaddr, bdaddr, sizeof(cp->bdaddr)); + memcpy(&cp->key, key, sizeof(cp->key)); + + syslog(LOG_DEBUG, "Sending Link_Key_Reply to '%s' " \ + "for remote bdaddr %x:%x:%x:%x:%x:%x", + addr->hci_node, + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + } else { + ng_hci_link_key_neg_rep_cp *cp = NULL; + + cmd->opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL, + NG_HCI_OCF_LINK_KEY_NEG_REP)); + cmd->length = sizeof(*cp); + + cp = (ng_hci_link_key_neg_rep_cp *)(cmd + 1); + memcpy(&cp->bdaddr, bdaddr, sizeof(cp->bdaddr)); + + syslog(LOG_DEBUG, "Sending Link_Key_Negative_Reply to '%s' " \ + "for remote bdaddr %x:%x:%x:%x:%x:%x", + addr->hci_node, + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + } + +again: + if (sendto(sock, buffer, sizeof(*cmd) + cmd->length, 0, + (struct sockaddr *) addr, sizeof(*addr)) < 0) { + if (errno == EINTR) + goto again; + + syslog(LOG_ERR, "Could not send link key reply to '%s' " \ + "for remote bdaddr %x:%x:%x:%x:%x:%x. %s (%d)", + addr->hci_node, + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0], + strerror(errno), errno); + return (-1); + } + + return (0); +} + +/* Signal handler */ +static void +sigint(int s) +{ + syslog(LOG_DEBUG, "Got signal %d, total number of signals %d", + s, ++ done); +} + +/* Display usage and exit */ +static void +usage(void) +{ + fprintf(stderr, +"Usage: %s [-d] -f config_file [-h]\n" \ +"Where:\n" \ +"\t-d do not detach from terminal\n" \ +"\t-f config_file use <config_file>\n" \ +"\t-h display this message\n", HCSECD_IDENT); + + exit(255); +} + diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.conf b/usr.sbin/bluetooth/hcsecd/hcsecd.conf new file mode 100644 index 000000000000..127ce04b74d6 --- /dev/null +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.conf @@ -0,0 +1,64 @@ +# +# $Id: hcsecd.conf,v 1.1 2002/11/24 20:22:39 max Exp $ +# $FreeBSD$ +# +# HCI security daemon configuration file +# +# Format: +# +# device { +# option value ; +# } +# +# Possible options and values +# +# Options Values +# ---------------------------------- +# bdaddr xx:xx:xx:xx:xx:xx ; - remote device BD_ADDR +# name "any char" ; - to set user friendly device name +# key 0x11223344 | nokey ; - to set link key for the device +# pin "secret" | nopin ; - to PIN code for the device +# +# Notes: +# +# Currently there is no way to select keys/PIN code based on which +# local device received the request. Everything is based on remote +# device BD_ADDR. +# +# "nokey" means that no link key has been defined and we should +# send Link_Key_Negative_Reply command to the device. +# +# "nopin" means that no PIN code has been defined and we should +# send PIN_Code_Negative_Reply command to the device +# + +# Default entry applied if no better match found +# It MUST have 00:00:00:00:00:00 as bdaddr +device { + bdaddr 00:00:00:00:00:00; + name "Default entry"; + key nokey; + pin nopin; +} + +device { + bdaddr 00:80:37:5e:4d:d4; + name "Ericsson T68 phone"; + key nokey; + pin "0000"; # PIN code (string up to 16 character) +} + +device { + bdaddr 00:01:03:fc:6e:ec; + name "3COM PCCARD"; + key nokey; + pin "0000"; +} + +device { + bdaddr 00:11:22:33:44:55; + name "Dummy"; + key 0x00112233445566778899aabbccddeeff; # 16 bytes key (hex string) + pin nopin; +} + diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.h b/usr.sbin/bluetooth/hcsecd/hcsecd.h new file mode 100644 index 000000000000..65820edc82f1 --- /dev/null +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.h @@ -0,0 +1,57 @@ +/* + * hcsecd.h + * + * 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: hcsecd.h,v 1.1 2002/11/24 20:22:39 max Exp $ + * $FreeBSD$ + */ + +#ifndef _HCSECD_H_ +#define _HCSECD_H_ 1 + +struct link_key +{ + bdaddr_t bdaddr; /* remote device BDADDR */ + char *name; /* remote device name */ + u_int8_t *key; /* link key (or NULL if no key) */ + char *pin; /* pin (or NULL if no pin) */ + LIST_ENTRY(link_key) next; /* link to the next */ +}; +typedef struct link_key link_key_t; +typedef struct link_key * link_key_p; + +extern char *config_file; + +#if __config_debug__ +void dump_config (void); +#endif + +void read_config_file(int s); +void clean_config (void); +link_key_p get_key (bdaddr_p bdaddr, int exact_match); + +#endif /* ndef _HCSECD_H_ */ + diff --git a/usr.sbin/bluetooth/hcsecd/lexer.l b/usr.sbin/bluetooth/hcsecd/lexer.l new file mode 100644 index 000000000000..2430d7e2982c --- /dev/null +++ b/usr.sbin/bluetooth/hcsecd/lexer.l @@ -0,0 +1,95 @@ +%{ +/* + * lexer.l + * + * 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: lexer.l,v 1.1 2002/11/24 20:22:39 max Exp $ + * $FreeBSD$ + */ + +#include <string.h> +#include "parser.h" +%} + +%option yylineno noyywrap nounput + +delim [ \t\n] +ws {delim}+ +empty {delim}* +comment \#.* + +hexdigit [0-9a-fA-F] +hexbyte {hexdigit}{hexdigit} + +device_word device +bdaddr_word bdaddr +name_word name +key_word key +nokey_word nokey +pin_word pin +nopin_word nopin + +bdaddrstring {hexbyte}:{hexbyte}:{hexbyte}:{hexbyte}:{hexbyte}:{hexbyte} +hexstring 0x{hexbyte}+ +string \".+\" + +%% + +\; return (';'); +\: return (':'); +\{ return ('{'); +\} return ('}'); + +{ws} ; +{empty} ; +{comment} ; + +{device_word} return (T_DEVICE); +{bdaddr_word} return (T_BDADDR); +{name_word} return (T_NAME); +{key_word} return (T_KEY); +{nokey_word} return (T_NOKEY); +{pin_word} return (T_PIN); +{nopin_word} return (T_NOPIN); + +{bdaddrstring} { + yylval.string = yytext; + return (T_BDADDRSTRING); + } + +{hexstring} { + yylval.string = &yytext[2]; + return (T_HEXSTRING); + } + +{string} { + yytext[strlen(yytext) - 1] = 0; + yylval.string = &yytext[1]; + return (T_STRING); + } + +%% + diff --git a/usr.sbin/bluetooth/hcsecd/parser.y b/usr.sbin/bluetooth/hcsecd/parser.y new file mode 100644 index 000000000000..750c068f9bc4 --- /dev/null +++ b/usr.sbin/bluetooth/hcsecd/parser.y @@ -0,0 +1,339 @@ +%{ +/* + * parser.y + * + * 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: parser.y,v 1.1 2002/11/24 20:22:39 max Exp $ + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <errno.h> +#include <ng_hci.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <syslog.h> +#include "hcsecd.h" + + int yyparse (void); + int yylex (void); + +static void free_key (link_key_p key); +static int hexa2int4(char *a); +static int hexa2int8(char *a); + +extern int yylineno; +static LIST_HEAD(, link_key) link_keys; + char *config_file = "/usr/local/etc/hcsecd.conf"; + +static link_key_p key = NULL; +%} + +%union { + char *string; +} + +%token <string> T_BDADDRSTRING T_HEXSTRING T_STRING +%token T_DEVICE T_BDADDR T_NAME T_KEY T_PIN T_NOKEY T_NOPIN T_JUNK + +%% + +config: line + | config line + ; + +line: T_DEVICE + { + key = (link_key_p) malloc(sizeof(*key)); + if (key == NULL) { + syslog(LOG_ERR, "Could not allocate new " \ + "config entry"); + exit(1); + } + + memset(key, 0, sizeof(*key)); + } + '{' options '}' + { + if (get_key(&key->bdaddr, 1) != NULL) { + syslog(LOG_ERR, "Ignoring duplicated entry " \ + "for bdaddr %x:%x:%x:%x:%x:%x", + key->bdaddr.b[5], + key->bdaddr.b[4], + key->bdaddr.b[3], + key->bdaddr.b[2], + key->bdaddr.b[1], + key->bdaddr.b[0]); + free_key(key); + } else + LIST_INSERT_HEAD(&link_keys, key, next); + + key = NULL; + } + ; + +options: option ';' + | options option ';' + ; + +option: bdaddr + | name + | key + | pin + ; + +bdaddr: T_BDADDR T_BDADDRSTRING + { + int a0, a1, a2, a3, a4, a5; + + if (sscanf($2, "%x:%x:%x:%x:%x:%x", + &a5, &a4, &a3, &a2, &a1, &a0) != 6) { + syslog(LOG_ERR, "Cound not parse BDADDR " \ + "'%s'", $2); + exit(1); + } + + key->bdaddr.b[0] = (a0 & 0xff); + key->bdaddr.b[1] = (a1 & 0xff); + key->bdaddr.b[2] = (a2 & 0xff); + key->bdaddr.b[3] = (a3 & 0xff); + key->bdaddr.b[4] = (a4 & 0xff); + key->bdaddr.b[5] = (a5 & 0xff); + } + ; + +name: T_NAME T_STRING + { + if (key->name != NULL) + free(key->name); + + key->name = strdup($2); + if (key->name == NULL) { + syslog(LOG_ERR, "Could not allocate new " \ + "device name"); + exit(1); + } + } + ; + +key: T_KEY T_HEXSTRING + { + int i, len; + + if (key->key != NULL) + free(key->key); + + key->key = (u_int8_t *) malloc(NG_HCI_KEY_SIZE); + if (key->key == NULL) { + syslog(LOG_ERR, "Could not allocate new " \ + "link key"); + exit(1); + } + + memset(key->key, 0, NG_HCI_KEY_SIZE); + + len = strlen($2) / 2; + if (len > NG_HCI_KEY_SIZE) + len = NG_HCI_KEY_SIZE; + + for (i = 0; i < len; i ++) + key->key[i] = hexa2int8((char *)($2) + 2*i); + } + | T_KEY T_NOKEY + { + if (key->key != NULL) + free(key->key); + + key->key = NULL; + } + ; + +pin: T_PIN T_STRING + { + if (key->pin != NULL) + free(key->pin); + + key->pin = strdup($2); + if (key->pin == NULL) { + syslog(LOG_ERR, "Could not allocate new " \ + "PIN code"); + exit(1); + } + } + | T_PIN T_NOPIN + { + if (key->pin != NULL) + free(key->pin); + + key->pin = NULL; + } + ; + +%% + +/* Display parser error message */ +void +yyerror(char const *message) +{ + syslog(LOG_ERR, "%s in line %d", message, yylineno); +} + +/* Re-read config file */ +void +read_config_file(int s) +{ + extern FILE *yyin; + + if (config_file == NULL) { + syslog(LOG_ERR, "Unknown config file name!"); + exit(1); + } + + if ((yyin = fopen(config_file, "r")) == NULL) { + syslog(LOG_ERR, "Could not open config file '%s'. %s (%d)", + config_file, strerror(errno), errno); + exit(1); + } + + clean_config(); + if (yyparse() < 0) { + syslog(LOG_ERR, "Could not parse config file '%s'",config_file); + exit(1); + } + + fclose(yyin); + yyin = NULL; + +#if __config_debug__ + dump_config(); +#endif +} + +/* Clean config */ +void +clean_config(void) +{ + link_key_p key = NULL; + + while ((key = LIST_FIRST(&link_keys)) != NULL) { + LIST_REMOVE(key, next); + free_key(key); + } +} + +/* Find link key entry in the list. Return exact or default match */ +link_key_p +get_key(bdaddr_p bdaddr, int exact_match) +{ + link_key_p key = NULL, defkey = NULL; + + LIST_FOREACH(key, &link_keys, next) { + if (memcmp(bdaddr, &key->bdaddr, sizeof(key->bdaddr)) == 0) + break; + + if (!exact_match) + if (memcmp(NG_HCI_BDADDR_ANY, &key->bdaddr, + sizeof(key->bdaddr)) == 0) + defkey = key; + } + + return ((key != NULL)? key : defkey); +} + +#if __config_debug__ +/* Dump config */ +void +dump_config(void) +{ + link_key_p key = NULL; + char buffer[64]; + + LIST_FOREACH(key, &link_keys, next) { + if (key->key != NULL) + snprintf(buffer, sizeof(buffer), +"0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + key->key[0], key->key[1], key->key[2], + key->key[3], key->key[4], key->key[5], + key->key[6], key->key[7], key->key[8], + key->key[9], key->key[10], key->key[11], + key->key[12], key->key[13], key->key[14], + key->key[15]); + + syslog(LOG_DEBUG, +"device %s " \ +"bdaddr %x:%x:%x:%x:%x:%x " \ +"pin %s " \ +"key %s", + (key->name != NULL)? key->name : "noname", + key->bdaddr.b[5], key->bdaddr.b[4], key->bdaddr.b[3], + key->bdaddr.b[2], key->bdaddr.b[1], key->bdaddr.b[0], + (key->pin != NULL)? key->pin : "nopin", + (key->key != NULL)? buffer : "nokey"); + } +} +#endif + +/* Free key entry */ +static void +free_key(link_key_p key) +{ + if (key->name != NULL) + free(key->name); + if (key->key != NULL) + free(key->key); + if (key->pin != NULL) + free(key->pin); + + memset(key, 0, sizeof(*key)); + free(key); +} + +/* Convert hex ASCII to int4 */ +static int +hexa2int4(char *a) +{ + if ('0' <= *a && *a <= '9') + return (*a - '0'); + + if ('A' <= *a && *a <= 'F') + return (*a - 'A' + 0xa); + + if ('a' <= *a && *a <= 'f') + return (*a - 'a' + 0xa); + + syslog(LOG_ERR, "Invalid hex character: '%c' (%#x)", *a, *a); + exit(1); +} + +/* Convert hex ASCII to int8 */ +static int +hexa2int8(char *a) +{ + return ((hexa2int4(a) << 4) | hexa2int4(a + 1)); +} + diff --git a/usr.sbin/bluetooth/hcseriald/Makefile b/usr.sbin/bluetooth/hcseriald/Makefile index 4153cd6b9ef5..4d6b6290a9e4 100644 --- a/usr.sbin/bluetooth/hcseriald/Makefile +++ b/usr.sbin/bluetooth/hcseriald/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.4 2002/09/04 21:29:58 max Exp $ +# $Id: Makefile,v 1.2 2003/03/15 03:07:45 max Exp $ # $FreeBSD$ DESTDIR= /usr/sbin/ @@ -8,7 +8,7 @@ PROG= hcseriald MAN8= hcseriald.8 WARNS?= 2 -CFLAGS+= -Wall -O2 -I../../../sys/netgraph/bluetooth/include +CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include SRCS= hcseriald.c DPADD= ${LIBNETGRAPH} diff --git a/usr.sbin/bluetooth/hcseriald/hcseriald.8 b/usr.sbin/bluetooth/hcseriald/hcseriald.8 index 41bef62cc99b..d605fa91cd96 100644 --- a/usr.sbin/bluetooth/hcseriald/hcseriald.8 +++ b/usr.sbin/bluetooth/hcseriald/hcseriald.8 @@ -1,6 +1,8 @@ +.\" hcseriald.8 +.\" .\" 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: @@ -9,7 +11,7 @@ .\" 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 @@ -21,9 +23,9 @@ .\" 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: hcseriald.8,v 1.2 2003/04/27 19:45:33 max Exp $ .\" $FreeBSD$ -.\" .Dd June 14, 2002 .Dt HCSERIALD 8 .Os @@ -33,52 +35,50 @@ .Sh SYNOPSIS .Nm .Op Fl f Ar device -.Op Fl n Ar node_name +.Op Fl n Ar node name .Op Fl s Ar speed -.Op Fl d +.Op Fl d +.Op Fl h .Sh DESCRIPTION The .Nm -utility -handles serial Bluetooth devices. -It does one simple thing. -It opens -specified serial device, sets device parameters and pushes -.Em H4 +handles serial Bluetooth devices. It does one simple thing. It opens +specified serial device, sets device parameters and pushes +.Em H4 line discipline. .Pp The options are as follows: .Bl -tag -width indent .It Fl f Ar device -Callout device name. -Example: -.Fl f Pa /dev/cuaa0 . -.It Fl n Ar node_name -Set H4 Netgraph node name. -Example: -.Fl n Li sio0 . +Callout device name. Example: +.Fl f +.Pa /dev/cuaa0 . +.It Fl n Ar node name +Set H4 Netgraph node name. Example: +.Fl n Ar sio0 . .It Fl s Ar speed Set serial device speed to -.Ar speed . +.Em speed . Example: -.Fl s Li 115200 . +.Fl s Ar 115200 . .It Fl d Do not disassociate from the controlling terminal, i.e. run in foreground. +.It Fl h +Display usage message and exit. .El .Sh FILES -.Bl -tag -width ".Pa /var/run/hcserial.*.pid" -compact +.Bl -tag -width /dev/consolectl -compact .It Pa /var/run/hcserial.*.pid -Process ID of the currently running +process id of the currently running .Nm -daemon, -where -.Ql * +daemon. Where +.Dq * is a H4 Netgraph node name. .El .Sh SEE ALSO +.Xr tty 4 , .Xr ng_h4 4 , .Xr ng_hci 4 , -.Xr tty 4 , .Xr hccontrol 8 .Sh AUTHORS .An Maksim Yevmenkin Aq m_evmenkin@yahoo.com diff --git a/usr.sbin/bluetooth/hcseriald/hcseriald.c b/usr.sbin/bluetooth/hcseriald/hcseriald.c index bb0e8190caaf..a4e7f546f718 100644 --- a/usr.sbin/bluetooth/hcseriald/hcseriald.c +++ b/usr.sbin/bluetooth/hcseriald/hcseriald.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: hcseriald.c,v 1.4 2002/09/04 21:29:58 max Exp $ + * $Id: hcseriald.c,v 1.2 2003/04/27 19:45:33 max Exp $ * $FreeBSD$ */ @@ -66,7 +66,7 @@ main(int argc, char *argv[]) struct sigaction sa; /* Process command line arguments */ - while ((n = getopt(argc, argv, "df:n:s:")) != -1) { + while ((n = getopt(argc, argv, "df:n:s:h")) != -1) { switch (n) { case 'd': detach = 0; @@ -86,6 +86,7 @@ main(int argc, char *argv[]) usage(argv[0]); break; + case 'h': default: usage(argv[0]); break; @@ -267,12 +268,13 @@ sighandler(int s) static void usage(void) { - fprintf(stderr, "Usage: %s -f device -n node_name [-s speed -d]\n" \ + fprintf(stderr, "Usage: %s -f device -n node_name [-s speed -d -h]\n" \ "Where:\n" \ "\t-f device tty device name, ex. /dev/cuaa1\n" \ "\t-n node_name set Netgraph node name to node_name\n" \ "\t-s speed set tty speed, ex. 115200\n" \ - "\t-d run in foreground\n", + "\t-d run in foreground\n" \ + "\t-h display this message\n", hcseriald); exit(255); } /* usage */ diff --git a/usr.sbin/bluetooth/l2control/Makefile b/usr.sbin/bluetooth/l2control/Makefile index b098874082e1..f6fb501c2326 100644 --- a/usr.sbin/bluetooth/l2control/Makefile +++ b/usr.sbin/bluetooth/l2control/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.3 2002/09/04 21:30:40 max Exp $ +# $Id: Makefile,v 1.2 2003/03/15 03:07:47 max Exp $ # $FreeBSD$ DESTDIR= /usr/sbin/ @@ -6,7 +6,7 @@ MANDIR= ../share/man/man PROG= l2control MAN8= l2control.8 WARNS?= 2 -CFLAGS+= -g -I../../../sys/netgraph/bluetooth/include +CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include SRCS= l2cap.c l2control.c .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/l2control/l2cap.c b/usr.sbin/bluetooth/l2control/l2cap.c index a0f2d240d579..ca4111d8e81a 100644 --- a/usr.sbin/bluetooth/l2control/l2cap.c +++ b/usr.sbin/bluetooth/l2control/l2cap.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: l2cap.c,v 1.6 2002/09/04 21:30:40 max Exp $ + * $Id: l2cap.c,v 1.4 2003/04/26 23:11:25 max Exp $ * $FreeBSD$ */ @@ -53,9 +53,6 @@ l2cap_read_node_flags(int s, int argc, char **argv) if (ioctl(s, SIOC_L2CAP_NODE_GET_FLAGS, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "BD_ADDR: %x:%x:%x:%x:%x:%x\n", - r.src.b[5], r.src.b[4], r.src.b[3], - r.src.b[2], r.src.b[1], r.src.b[0]); fprintf(stdout, "Connectionless traffic flags:\n"); fprintf(stdout, "\tSDP: %s\n", (r.flags & NG_L2CAP_CLT_SDP_DISABLED)? "disabled" : "enabled"); @@ -77,9 +74,6 @@ l2cap_read_debug_level(int s, int argc, char **argv) if (ioctl(s, SIOC_L2CAP_NODE_GET_DEBUG, &r, sizeof(r)) < 0) return (ERROR); - fprintf(stdout, "BD_ADDR: %x:%x:%x:%x:%x:%x\n", - r.src.b[5], r.src.b[4], r.src.b[3], - r.src.b[2], r.src.b[1], r.src.b[0]); fprintf(stdout, "Debug level: %d\n", r.debug); return (OK); @@ -135,17 +129,14 @@ l2cap_read_connection_list(int s, int argc, char **argv) goto out; } - fprintf(stdout, "BD_ADDR: %x:%x:%x:%x:%x:%x\n", - r.src.b[5], r.src.b[4], r.src.b[3], - r.src.b[2], r.src.b[1], r.src.b[0]); fprintf(stdout, "L2CAP connections:\n"); fprintf(stdout, "Remote BD_ADDR Handle Flags Pending State\n"); for (n = 0; n < r.num_connections; n++) { fprintf(stdout, "%02x:%02x:%02x:%02x:%02x:%02x " \ - " %5d " \ - "%2.2s %2.2s " \ + "%6d " \ + "%c%c%c%c%c " \ "%7d " \ "%s\n", r.connections[n].remote.b[5], @@ -155,8 +146,11 @@ l2cap_read_connection_list(int s, int argc, char **argv) r.connections[n].remote.b[1], r.connections[n].remote.b[0], r.connections[n].con_handle, - ((r.connections[n].flags & NG_L2CAP_CON_TX)? "TX" : ""), - ((r.connections[n].flags & NG_L2CAP_CON_RX)? "RX" : ""), + ((r.connections[n].flags & NG_L2CAP_CON_OUTGOING)? 'O' : 'I'), + ((r.connections[n].flags & NG_L2CAP_CON_LP_TIMO)? 'L' : ' '), + ((r.connections[n].flags & NG_L2CAP_CON_AUTO_DISCON_TIMO)? 'D' : ' '), + ((r.connections[n].flags & NG_L2CAP_CON_TX)? 'T' : ' '), + ((r.connections[n].flags & NG_L2CAP_CON_RX)? 'R' : ' '), r.connections[n].pending, con_state2str(r.connections[n].state)); } @@ -198,9 +192,6 @@ l2cap_read_channel_list(int s, int argc, char **argv) goto out; } - fprintf(stdout, "BD_ADDR: %x:%x:%x:%x:%x:%x\n", - r.src.b[5], r.src.b[4], r.src.b[3], - r.src.b[2], r.src.b[1], r.src.b[0]); fprintf(stdout, "L2CAP channels:\n"); fprintf(stdout, "Remote BD_ADDR SCID/ DCID PSM IMTU/ OMTU State\n"); @@ -224,6 +215,46 @@ out: return (error); } /* l2cap_read_channel_list */ +/* Send read_auto_disconnect_timeout command to the node */ +static int +l2cap_read_auto_disconnect_timeout(int s, int argc, char **argv) +{ + struct ng_btsocket_l2cap_raw_auto_discon_timo r; + + memset(&r, 0, sizeof(r)); + if (ioctl(s, SIOC_L2CAP_NODE_GET_AUTO_DISCON_TIMO, &r, sizeof(r)) < 0) + return (ERROR); + + if (r.timeout != 0) + fprintf(stdout, "Auto disconnect timeout: %d sec\n", r.timeout); + else + fprintf(stdout, "Auto disconnect disabled\n"); + + return (OK); +} /* l2cap_read_auto_disconnect_timeout */ + +/* Send write_auto_disconnect_timeout command to the node */ +static int +l2cap_write_auto_disconnect_timeout(int s, int argc, char **argv) +{ + struct ng_btsocket_l2cap_raw_auto_discon_timo r; + + memset(&r, 0, sizeof(r)); + switch (argc) { + case 1: + r.timeout = atoi(argv[0]); + break; + + default: + return (USAGE); + } + + if (ioctl(s, SIOC_L2CAP_NODE_SET_AUTO_DISCON_TIMO, &r, sizeof(r)) < 0) + return (ERROR); + + return (OK); +} /* l2cap_write_auto_disconnect_timeout */ + struct l2cap_command l2cap_commands[] = { { "read_node_flags", @@ -251,6 +282,16 @@ struct l2cap_command l2cap_commands[] = { &l2cap_read_channel_list }, { +"read_auto_disconnect_timeout", +"Get L2CAP node auto disconnect timeout (in sec)", +&l2cap_read_auto_disconnect_timeout +}, +{ +"write_auto_disconnect_timeout <timeout>", +"Set L2CAP node auto disconnect timeout (in sec)", +&l2cap_write_auto_disconnect_timeout +}, +{ NULL, }}; diff --git a/usr.sbin/bluetooth/l2control/l2control.8 b/usr.sbin/bluetooth/l2control/l2control.8 index 51018b4b3695..fb092761e654 100644 --- a/usr.sbin/bluetooth/l2control/l2control.8 +++ b/usr.sbin/bluetooth/l2control/l2control.8 @@ -1,6 +1,8 @@ +.\" l2control.8 +.\" .\" 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: @@ -9,7 +11,7 @@ .\" 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 @@ -21,9 +23,9 @@ .\" 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: l2control.8,v 1.3 2003/04/27 19:45:34 max Exp $ .\" $FreeBSD$ -.\" .Dd June 14, 2002 .Dt L2CONTROL 8 .Os @@ -32,38 +34,33 @@ .Nd L2CAP configuration utility .Sh SYNOPSIS .Nm -.Op Fl a Ar BD_ADDR -.Op Ar command +.Op Fl a Ar local BD_ADDR +.Op Fl h +.Op Ar command .Op Ar parameters ... .Sh DESCRIPTION The .Nm -utility connects to the local device with specified -.Ar BD_ADDR -and attempts to send specified -.Ar command . -The +utility connects to the local device with specified BD_ADDR and attempts +to send specified command. .Nm -utility -will print results to the standard output and error messages to +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 a Ar BD_ADDR -Connect to the local device with specified -.Ar BD_ADDR . -Example: -.Fl a Li 00:01:02:03:04:05 . -.It Ar command -One of the supported commands (see below). -Special command -.Cm help -can be used to obtain the list of all supported commands. -To get more +.It Fl a Ar local BD_ADDR +Connect to the local device with specified BD_ADDR. Example: +.Fl a Ar 00:01:02:03:04:05 . +.It Fl h +Display usage message and exit. +.It command +One of the supported commands (see below). Special command +.Dq help +can be used to obtain the list of all supported commands. To get more information about specific command use -.Cm help Ar command . -.It Ar parameters +.Dq help command . +.It parameters One or more optional space separated command parameters. .El .Sh COMMANDS @@ -71,13 +68,16 @@ The currently supported node commands in .Nm are: .Pp -.Bl -tag -offset indent -compact -.It Cm Read_Node_Flags -.It Cm Read_Debug_Level -.It Cm Write_Debug_Level -.It Cm Read_Connection_List -.It Cm Read_Channel_List -.El +.Bd -literal -offset indent -compact +Read_Node_Flags +Read_Debug_Level +Write_Debug_Level +Read_Connection_List +Read_Channel_List +Read_Auto_Disconnect_Timeout +Write_Auto_Disconnect_Timeout +.Ed +.Pp .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO diff --git a/usr.sbin/bluetooth/l2control/l2control.c b/usr.sbin/bluetooth/l2control/l2control.c index ef658265fb9f..a2596570d190 100644 --- a/usr.sbin/bluetooth/l2control/l2control.c +++ b/usr.sbin/bluetooth/l2control/l2control.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: l2control.c,v 1.5 2002/09/04 21:30:40 max Exp $ + * $Id: l2control.c,v 1.3 2003/04/27 19:45:34 max Exp $ * $FreeBSD$ */ @@ -61,7 +61,7 @@ main(int argc, char *argv[]) memset(&bdaddr, 0, sizeof(bdaddr)); /* Process command line arguments */ - while ((n = getopt(argc, argv, "a:")) != -1) { + while ((n = getopt(argc, argv, "a:h")) != -1) { switch (n) { case 'a': { int a0, a1, a2, a3, a4, a5; @@ -80,6 +80,7 @@ main(int argc, char *argv[]) bdaddr.b[5] = (a5 & 0xff); } break; + case 'h': default: usage(); break; @@ -148,13 +149,6 @@ do_l2cap_command(bdaddr_p bdaddr, int argc, char **argv) sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2], sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]); - if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) - err(2, -"Could not connect socket, bdaddr=%x:%x:%x:%x:%x:%x", - sa.l2cap_bdaddr.b[5], sa.l2cap_bdaddr.b[4], - sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2], - sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]); - e = 0x0ffff; if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &e, sizeof(e)) < 0) err(3, "Coult not setsockopt(RCVBUF, %d)", e); @@ -220,7 +214,7 @@ print_l2cap_command(struct l2cap_command *category) static void usage(void) { - fprintf(stdout, "Usage: l2control -a BD_ADDR cmd [p1] [..]]\n"); + fprintf(stdout, "Usage: l2control -a BD_ADDR [-h] cmd [p1] [..]]\n"); exit(255); } /* usage */ diff --git a/usr.sbin/bluetooth/l2control/l2control.h b/usr.sbin/bluetooth/l2control/l2control.h index 0f6e5dca3508..43d456164be8 100644 --- a/usr.sbin/bluetooth/l2control/l2control.h +++ b/usr.sbin/bluetooth/l2control/l2control.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: l2control.h,v 1.2 2002/09/04 21:30:40 max Exp $ + * $Id: l2control.h,v 1.1 2002/11/24 20:22:41 max Exp $ * $FreeBSD$ */ diff --git a/usr.sbin/bluetooth/l2ping/Makefile b/usr.sbin/bluetooth/l2ping/Makefile index f2dad3196d1b..d99143b798a7 100644 --- a/usr.sbin/bluetooth/l2ping/Makefile +++ b/usr.sbin/bluetooth/l2ping/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.4 2002/09/04 21:28:05 max Exp $ +# $Id: Makefile,v 1.2 2003/03/15 03:07:49 max Exp $ # $FreeBSD$ DESTDIR= /usr/sbin/ @@ -7,6 +7,6 @@ PROG= l2ping MAN8= l2ping.8 SRCS= l2ping.c WARNS?= 2 -CFLAGS+= -g -I../../../sys/netgraph/bluetooth/include +CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/l2ping/l2ping.8 b/usr.sbin/bluetooth/l2ping/l2ping.8 index 7c5cc798eb5a..831eef87baa4 100644 --- a/usr.sbin/bluetooth/l2ping/l2ping.8 +++ b/usr.sbin/bluetooth/l2ping/l2ping.8 @@ -1,6 +1,8 @@ +.\" l2ping.8 +.\" .\" 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: @@ -9,7 +11,7 @@ .\" 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 @@ -21,9 +23,9 @@ .\" 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: l2ping.8,v 1.2 2003/04/27 19:45:35 max Exp $ .\" $FreeBSD$ -.\" .Dd June 14, 2002 .Dt L2PING 8 .Os @@ -32,61 +34,51 @@ .Nd send L2CAP ECHO_REQUEST to remote devices .Sh SYNOPSIS .Nm -.Op Fl a Ar BD_ADDR -.Op Fl S Ar BD_ADDR +.Op Fl a Ar remote BD_ADDR +.Op Fl S Ar source BD_ADDR .Op Fl c Ar count .Op Fl f .Op Fl i Ar delay .Op Fl s Ar size +.Op Fl h .Sh DESCRIPTION The .Nm -uses L2CAP -.Dv ECHO_REQUEST -datagram to elicit a L2CAP -.Dv ECHO_RESPONSE -from a remote device. +uses L2CAP ECHO_REQUEST datagram to elicit a L2CAP ECHO_RESPONSE from a +remote device. .Pp The options are as follows: .Bl -tag -width indent -.It Fl a Ar BD_ADDR -Address of remote device to ping. -Example: -.Fl a Li 00:01:02:03:04:05 . -.It Fl S Ar BD_ADDR -Send L2CAP -.Dv ECHO_REQUEST -from local device that has -.Ar BD_ADDR . -Example: -.Fl S Li 00:05:04:03:02:01 . +.It Fl a Ar remote BD_ADDR +Address of remote device to ping. Example: +.Fl a Ar 00:01:02:03:04:05 . +.It Fl S Ar source BD_ADDR +Send L2CAP ECHO_REQUEST from local device that has BD_ADDR. Example: +.Fl S Ar 00:05:04:03:02:01 . .It Fl c Ar count -Number of packets to send. -If this option is not specified, +Number of packets to send. If this option is not specified, .Nm will operate until interrupted. .It Fl f .Dq Flood -ping, i.e., no delay between packets. +ping, i.e. no delay between packets. .It Fl i Ar wait -Wait -.Ar wait -seconds between sending each packet. -The default is to wait for one -second between each packet. -This option is ignored if -.Fl f +Wait +.Em wait +seconds between sending each packet. The default is to wait for one +second between each packet. This option is ignored if +.Fl f has been specified. .It Fl s Ar size -Specify the number of payload bytes to be sent. -The default is 64. -The maximum size is 65531. -Use this option with caution. -Some implementations may not like large sizes and may hang or even crash. +Specify the number of payload bytes to be sent. The default is 64. The +maximum size is 65531. Use this option with caution. Some implementations +may not like large sizes and may hang or even crash. +.It Fl h +Display usage message and exit. .El .Sh BUGS -Could collect more statistics. -Could check for duplicated, corrupted and lost packets. +Could collect more statistic. Could check for duplicated, corrupted +and lost packets. .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO diff --git a/usr.sbin/bluetooth/l2ping/l2ping.c b/usr.sbin/bluetooth/l2ping/l2ping.c index a7ffd3771d56..5f3bc281febf 100644 --- a/usr.sbin/bluetooth/l2ping/l2ping.c +++ b/usr.sbin/bluetooth/l2ping/l2ping.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: l2ping.c,v 1.9 2002/09/04 21:28:05 max Exp $ + * $Id: l2ping.c,v 1.3 2003/04/27 19:45:36 max Exp $ * $FreeBSD$ */ @@ -64,11 +64,16 @@ static char const pattern[] = "1234567890-"; int main(int argc, char *argv[]) { + bdaddr_t src, dst; + struct sockaddr_l2cap sa; struct ng_btsocket_l2cap_raw_ping r; int n, s, count, wait, flood, fail; struct timeval a, b; /* Set defaults */ + memcpy(&src, NG_HCI_BDADDR_ANY, sizeof(src)); + memcpy(&dst, NG_HCI_BDADDR_ANY, sizeof(dst)); + memset(&r, 0, sizeof(r)); r.echo_data = calloc(NG_L2CAP_MAX_ECHO_SIZE, sizeof(u_int8_t)); if (r.echo_data == NULL) { @@ -82,7 +87,7 @@ main(int argc, char *argv[]) flood = 0; /* Parse command line arguments */ - while ((n = getopt(argc, argv, "a:c:fi:n:s:S:")) != -1) { + while ((n = getopt(argc, argv, "a:c:fi:n:s:S:h")) != -1) { switch (n) { case 'a': case 'S': { @@ -94,20 +99,20 @@ main(int argc, char *argv[]) if (n == 'a') { /* destination bdaddr */ - r.echo_dst.b[0] = (a0 & 0xff); - r.echo_dst.b[1] = (a1 & 0xff); - r.echo_dst.b[2] = (a2 & 0xff); - r.echo_dst.b[3] = (a3 & 0xff); - r.echo_dst.b[4] = (a4 & 0xff); - r.echo_dst.b[5] = (a5 & 0xff); + dst.b[0] = (a0 & 0xff); + dst.b[1] = (a1 & 0xff); + dst.b[2] = (a2 & 0xff); + dst.b[3] = (a3 & 0xff); + dst.b[4] = (a4 & 0xff); + dst.b[5] = (a5 & 0xff); } else { /* source bdaddr */ - r.echo_src.b[0] = (a0 & 0xff); - r.echo_src.b[1] = (a1 & 0xff); - r.echo_src.b[2] = (a2 & 0xff); - r.echo_src.b[3] = (a3 & 0xff); - r.echo_src.b[4] = (a4 & 0xff); - r.echo_src.b[5] = (a5 & 0xff); + src.b[0] = (a0 & 0xff); + src.b[1] = (a1 & 0xff); + src.b[2] = (a2 & 0xff); + src.b[3] = (a3 & 0xff); + src.b[4] = (a4 & 0xff); + src.b[5] = (a5 & 0xff); } } break; @@ -136,41 +141,43 @@ main(int argc, char *argv[]) r.echo_size = NG_L2CAP_MAX_ECHO_SIZE; break; + case 'h': default: usage(); break; } } - if (memcmp(&r.echo_dst, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) + if (memcmp(&dst, NG_HCI_BDADDR_ANY, sizeof(dst)) == 0) usage(); s = socket(PF_BLUETOOTH, SOCK_RAW, BLUETOOTH_PROTO_L2CAP); if (s < 0) err(2, "Could not create socket"); - if (memcmp(&r.echo_src, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) != 0) { - struct sockaddr_l2cap sa; - - memset(&sa, 0, sizeof(sa)); - sa.l2cap_len = sizeof(sa); - sa.l2cap_family = AF_BLUETOOTH; - memcpy(&sa.l2cap_bdaddr, &r.echo_src, sizeof(bdaddr_t)); + memset(&sa, 0, sizeof(sa)); + sa.l2cap_len = sizeof(sa); + sa.l2cap_family = AF_BLUETOOTH; + memcpy(&sa.l2cap_bdaddr, &src, sizeof(sa.l2cap_bdaddr)); - if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) - err(3, + if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) + err(3, "Could not bind socket, src bdaddr=%x:%x:%x:%x:%x:%x", - sa.l2cap_bdaddr.b[5], sa.l2cap_bdaddr.b[4], - sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2], - sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]); - - if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) - err(4, -"Could not connect socket, src bdaddr=%x:%x:%x:%x:%x:%x", - sa.l2cap_bdaddr.b[5], sa.l2cap_bdaddr.b[4], - sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2], - sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]); - } + sa.l2cap_bdaddr.b[5], sa.l2cap_bdaddr.b[4], + sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2], + sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]); + + memset(&sa, 0, sizeof(sa)); + sa.l2cap_len = sizeof(sa); + sa.l2cap_family = AF_BLUETOOTH; + memcpy(&sa.l2cap_bdaddr, &dst, sizeof(sa.l2cap_bdaddr)); + + if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) + err(4, +"Could not connect socket, dst bdaddr=%x:%x:%x:%x:%x:%x", + sa.l2cap_bdaddr.b[5], sa.l2cap_bdaddr.b[4], + sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2], + sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]); /* Fill pattern */ for (n = 0; n < r.echo_size; ) { @@ -206,9 +213,8 @@ main(int argc, char *argv[]) fprintf(stdout, "%d bytes from %x:%x:%x:%x:%x:%x seq_no=%d time=%.3f ms result=%#x %s\n", r.echo_size, - r.echo_dst.b[5], r.echo_dst.b[4], - r.echo_dst.b[3], r.echo_dst.b[2], - r.echo_dst.b[1], r.echo_dst.b[0], + dst.b[5], dst.b[4], dst.b[3], + dst.b[2], dst.b[1], dst.b[0], ntohl(*((int *)(r.echo_data))), tv2msec(&b), r.result, ((fail == 0)? "" : strerror(errno))); @@ -264,7 +270,7 @@ static void usage(void) { fprintf(stderr, "Usage: l2ping -a bd_addr " \ - "[-S bd_addr -c count -i wait -s size]\n"); + "[-S bd_addr -c count -i wait -s size -h]\n"); fprintf(stderr, "Where:\n"); fprintf(stderr, "\t-S bd_addr - Source BD_ADDR\n"); fprintf(stderr, "\t-a bd_addr - Remote BD_ADDR to ping\n"); @@ -273,6 +279,7 @@ usage(void) fprintf(stderr, "\t-i wait - Delay between packets (sec)\n"); fprintf(stderr, "\t-s size - Packet size (bytes), " \ "between %d and %d\n", sizeof(int), NG_L2CAP_MAX_ECHO_SIZE); + fprintf(stderr, "\t-h - Display this message\n"); exit(255); } /* usage */ diff --git a/usr.sbin/bluetooth/rfcomm_pppd/Makefile b/usr.sbin/bluetooth/rfcomm_pppd/Makefile new file mode 100644 index 000000000000..0269123c9d40 --- /dev/null +++ b/usr.sbin/bluetooth/rfcomm_pppd/Makefile @@ -0,0 +1,13 @@ +# $Id: Makefile,v 1.2 2003/03/15 03:07:50 max Exp $ +# $FreeBSD$ + +DESTDIR= /usr/sbin/ +MANDIR= ../share/man/man +PROG= rfcomm_pppd +MAN8= rfcomm_pppd.8 +WARNS?= 2 +CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include +SRCS= rfcomm_pppd.c + +.include <bsd.prog.mk> + diff --git a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.8 b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.8 new file mode 100644 index 000000000000..dbf974e293af --- /dev/null +++ b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.8 @@ -0,0 +1,246 @@ +.\" rfcomm_pppd.8 +.\" +.\" Copyright (c) 2001-2003 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: rfcomm_pppd.8,v 1.5 2003/04/27 19:45:37 max Exp $ +.\" $FreeBSD$ +.Dd February 4, 2003 +.Dt RFCOMM_PPPD 8 +.Os +.Sh NAME +.Nm rfcomm_pppd +.Nd RFCOMM PPP daemon +.Sh SYNOPSIS +.Nm +.Op Fl a Ar BD_ADDR +.Op Fl c +.Op Fl C Ar channel +.Op Fl d +.Op Fl h +.Op Fl l Ar label +.Op Fl s +.Sh DESCRIPTION +The +.Nm +daemon is a simple wrapper daemon that allows to use standard +.Nm ppp +on RFCOMM connection. It can operate in two modes: client and server. +.Pp +In the client mode +.Nm +opens a RFCOMM connection to the specified server's BD_ADRR and channel. +Once RFCOMM connection is established +.Nm +executes +.Nm ppp +in +.Dq direct +mode with the specified label. The +.Nm ppp +in its turn operates over the RFCOMM connection just like it would operate +over the standard serial port thus allowing user to +.Dq dial out +and connect to the Internet. +.Pp +In the server mode +.Nm +opens a RFCOMM socket and listens for incomming connections from remote +clients. Once new incomming connection is accepted +.Nm +forks and executes +.Nm ppp +in +.Dq direct +mode with the specified label. The +.Nm ppp +in its turn operates over the RFCOMM connection just like it would operate over +the standard serial port thus providing network connectivity to remote clients. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl a Ar BD_ADDR +In the client mode this requied option specifies the remote BD_ADDR of the +RFCOMM server. In the server mode this option can be used to specify the local +BD_ADDR to listen on. By default server will listen on +.Dv ANY +address. +.It Fl c +Act as RFCOMM client. This is the default mode. +.It Fl C Ar channel +In both client and server modes this required option specifies RFCOMM channel +to connect to or listen on. +.It Fl d +Do not detach from the controlling terminal, i.e. run in foreground. +.It Fl h +Display usage message and exit. +.It Fl l Ar label +In both client and server modes this required option specifies which PPP label +will be used. +.It Fl s +Act as RFCOMM server. +.El +.Sh PPP CONFIGURATION +.Ss Important notes on PPP configuration +Special attention is required when adding new RFCOMM configurations to the +existing PPP configuration. Please keep in mind that PPP will +.Em always +execute commands in the +.Dq default +label of your +.Pa /etc/ppp/ppp.conf +file. Please make sure that the +.Dq default +label +.Em only +contains commands that apply to +.Em every +other label. If you need to use PPP for both dialing out and accepting incoming +RFCOMM connections, please make sure you have moved all commands related to +dialing out from the +.Dq default +section into appropriate outgoing label. +.Ss RFCOMM server +One of the typical examples is LAN access. In this example RFCOMM connection +is used as a null-modem connection between client and server. Both client +and server will start talking PPP right after RFCOMM connection was established. +.Bd -literal -offset indent +rfcomm-server: + set timeout 0 + set lqrperiod 10 + set ifaddr 10.0.0.1 10.0.0.2 255.255.255.0 + enable lqr + accept lqr + # Do not use PPP authentication. Assume that + # Bluetooth connection was authenticated already + disable pap + deny pap + disable chap + deny chap +.Ed +.Ss RFCOMM client +.Nm +supports both LAN and DUN (DialUp Networking) access. The client's +configuration for the LAN access is very similar to server's and might +look like this. +.Bd -literal -offset indent +rfcomm-client: + enable lqr + accept lqr + set dial + set timeout 0 + disable iface-alias + set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.0 0.0.0.0 + # Do not use PPP authentication. Assume that + # Bluetooth connection was authenticated already + deny pap + disable pap + deny chap + disable chap +.Ed +.Pp +The client's configuration for the DUN access is different. In this scenario +the client gets connected to the virtual serial port on the server. To open a +PPP session client must dial a number. Note that by default +.Nm ppp +will not execute any configured chat scripts. The +.Dq force-scripts +option can be used to override this behavior. The example of such configuration +is shown below. +.Bd -literal -offset indent +rfcomm-dialup: + # This is IMPORTANT option + enable force-scripts + + # You might want to change these + set authname + set authkey + set phone "*99***1#" + + # You might want to adjust dial string as well + set dial "ABORT BUSY ABORT NO\\\sCARRIER TIMEOUT 5 \\ + \\"\\" AT OK-AT-OK ATE1Q0 OK \\\\dATD\\\\T TIMEOUT 40 CONNECT" + set login + set timeout 30 + enable dns + resolv rewrite + + set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.0 0.0.0.0 + add default HISADDR +.Ed +.Pp +Note that by adjusting initialization string one can make CSD (Circuit +Switched Data), HSCSD (High Speed Circuit Switched Data) or GPRS (General +Packet Radio Service) connection. The availability of the particular connection +type depends on the phone model and service plan activated on the phone. +.Sh EXAMPLES +.Bl -tag -width indent +.It rfcomm_pppd -s -a 00:01:02:03:04:05 -C 1 -l rfcomm-server +.Pp +Will start +.Nm +in the server mode. The RFCOMM server will listen on local address +.Em 00:01:02:03:04:05 +and channel +.Em 1 . +Once incomming connection has been accepted +.Nm +will execute +.Nm ppp +in +.Dq direct +mode with +.Dq rfcomm-server +label. +.It rfcomm_pppd -c -a 00:01:02:03:04:05 -C 1 -l rfcomm-client +.Pp +Will start +.Nm +in the client mode. +.Nm +will try to connect to the RFCOMM server at +.Em 00:01:02:03:04:05 +address and channel +.Em 1 . +Once connected the +.Nm +will execute +.Nm ppp +in +.Dq direct +mode with +.Dq rfcomm-client +label. +.El +.Sh DIAGNOSTICS +.Ex -std +.Sh BUGS +.Nm +currently is not integrated with SDP (Service Discovery Protocol). +.Sh SEE ALSO +.Xr ppp 8 , +.Xr ng_btsocket 4 , +.Xr rfcomm_sppd 1 +.Sh AUTHORS +.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com diff --git a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c new file mode 100644 index 000000000000..160988eeed3c --- /dev/null +++ b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c @@ -0,0 +1,332 @@ +/* + * rfcomm_pppd.c + * + * Copyright (c) 2001-2003 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: rfcomm_pppd.c,v 1.3 2003/04/26 23:59:49 max Exp $ + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <bitstring.h> +#include <errno.h> +#include <fcntl.h> +#include <ng_hci.h> +#include <ng_l2cap.h> +#include <ng_btsocket.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +#define RFCOMM_PPPD "rfcomm_pppd" + +static void exec_ppp (int s, char *label); +static void sighandler (int s); +static void usage (void); + +static int done; + +/* Main */ +int +main(int argc, char *argv[]) +{ + struct sockaddr_rfcomm sock_addr; + char *label = NULL; + bdaddr_t addr; + int s, channel, detach, server; + pid_t pid; + + memcpy(&addr, NG_HCI_BDADDR_ANY, sizeof(addr)); + channel = 0; + detach = 1; + server = 0; + + /* Parse command line arguments */ + while ((s = getopt(argc, argv, "a:cC:dhl:s")) != -1) { + switch (s) { + case 'a': { /* BDADDR */ + int a0, a1, a2, a3, a4, a5; + + if (sscanf(optarg, "%x:%x:%x:%x:%x:%x", + &a5, &a4, &a3, &a2, &a1, &a0) != 6) + usage(); + /* NOT REACHED */ + + addr.b[0] = a0 & 0xff; + addr.b[1] = a1 & 0xff; + addr.b[2] = a2 & 0xff; + addr.b[3] = a3 & 0xff; + addr.b[4] = a4 & 0xff; + addr.b[5] = a5 & 0xff; + } break; + + case 'c': /* client */ + server = 0; + break; + + case 'C': /* RFCOMM channel */ + channel = atoi(optarg); + break; + + case 'd': /* do not detach */ + detach = 0; + break; + + case 'l': /* PPP label */ + label = optarg; + break; + + case 's': + server = 1; + break; + + case 'h': + default: + usage(); + /* NOT REACHED */ + } + } + + /* Check if we got everything we wanted */ + if ((channel <= 0 || channel > 30) || label == NULL || + (!server && memcmp(&addr, NG_HCI_BDADDR_ANY, sizeof(addr)) == 0)) + usage(); + /* NOT REACHED */ + + openlog(RFCOMM_PPPD, LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_USER); + + if (detach) { + pid = fork(); + if (pid == (pid_t) -1) { + syslog(LOG_ERR, "Could not fork(). %s (%d)", + strerror(errno), errno); + exit(1); + } + + if (pid != 0) + exit(0); + + if (daemon(0, 0) < 0) { + syslog(LOG_ERR, "Could not daemon(0, 0). %s (%d)", + strerror(errno), errno); + exit(1); + } + } + + s = socket(PF_BLUETOOTH, SOCK_STREAM, BLUETOOTH_PROTO_RFCOMM); + if (s < 0) { + syslog(LOG_ERR, "Could not create socket. %s (%d)", + strerror(errno), errno); + exit(1); + } + + if (server) { + struct sigaction sa; + + /* Install signal handler */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sighandler; + + if (sigaction(SIGTERM, &sa, NULL) < 0) { + syslog(LOG_ERR, "Could not sigaction(SIGTERM). %s (%d)", + strerror(errno), errno); + exit(1); + } + + if (sigaction(SIGHUP, &sa, NULL) < 0) { + syslog(LOG_ERR, "Could not sigaction(SIGHUP). %s (%d)", + strerror(errno), errno); + exit(1); + } + + if (sigaction(SIGINT, &sa, NULL) < 0) { + syslog(LOG_ERR, "Could not sigaction(SIGINT). %s (%d)", + strerror(errno), errno); + exit(1); + } + + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDWAIT; + + if (sigaction(SIGCHLD, &sa, NULL) < 0) { + syslog(LOG_ERR, "Could not sigaction(SIGCHLD). %s (%d)", + strerror(errno), errno); + exit(1); + } + + /* bind socket and listen for incoming connections */ + sock_addr.rfcomm_len = sizeof(sock_addr); + sock_addr.rfcomm_family = AF_BLUETOOTH; + memcpy(&sock_addr.rfcomm_bdaddr, &addr, + sizeof(sock_addr.rfcomm_bdaddr)); + sock_addr.rfcomm_channel = channel; + + if (bind(s, (struct sockaddr *) &sock_addr, + sizeof(sock_addr)) < 0) { + syslog(LOG_ERR, "Could not bind socket. %s (%d)", + strerror(errno), errno); + exit(1); + } + + if (listen(s, 10) < 0) { + syslog(LOG_ERR, "Could not listen on socket. %s (%d)", + strerror(errno), errno); + exit(1); + } + + for (done = 0; !done; ) { + int len = sizeof(sock_addr); + int s1 = accept(s, (struct sockaddr *) &sock_addr, &len); + + if (s1 < 0) { + syslog(LOG_ERR, "Could not accept connection " \ + "on socket. %s (%d)", strerror(errno), + errno); + exit(1); + } + + pid = fork(); + if (pid == (pid_t) -1) { + syslog(LOG_ERR, "Could not fork(). %s (%d)", + strerror(errno), errno); + exit(1); + } + + if (pid == 0) { + close(s); + + /* Reset signal handler */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGHUP, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGCHLD, &sa, NULL); + + /* Become daemon */ + daemon(0, 0); + + exec_ppp(s1, label); + } else + close(s1); + } + } else { + sock_addr.rfcomm_len = sizeof(sock_addr); + sock_addr.rfcomm_family = AF_BLUETOOTH; + memcpy(&sock_addr.rfcomm_bdaddr, NG_HCI_BDADDR_ANY, + sizeof(sock_addr.rfcomm_bdaddr)); + sock_addr.rfcomm_channel = 0; + + if (bind(s, (struct sockaddr *) &sock_addr, + sizeof(sock_addr)) < 0) { + syslog(LOG_ERR, "Could not bind socket. %s (%d)", + strerror(errno), errno); + exit(1); + } + + memcpy(&sock_addr.rfcomm_bdaddr, &addr, + sizeof(sock_addr.rfcomm_bdaddr)); + sock_addr.rfcomm_channel = channel; + + if (connect(s, (struct sockaddr *) &sock_addr, + sizeof(sock_addr)) < 0) { + syslog(LOG_ERR, "Could not connect socket. %s (%d)", + strerror(errno), errno); + exit(1); + } + + exec_ppp(s, label); + } + + exit(0); +} /* main */ + +/* + * Redirects stdin/stdout to s, stderr to /dev/null and exec ppp -direct label. + * Never retruns. + */ + +static void +exec_ppp(int s, char *label) +{ + char ppp[] = "/usr/sbin/ppp"; + char *ppp_args[] = { ppp, "-direct", NULL, NULL }; + + close(0); + if (dup(s) < 0) { + syslog(LOG_ERR, "Could not dup(0). %s (%d)", + strerror(errno), errno); + exit(1); + } + + close(1); + if (dup(s) < 0) { + syslog(LOG_ERR, "Could not dup(1). %s (%d)", + strerror(errno), errno); + exit(1); + } + + close(2); + open("/dev/null", O_RDWR); + + ppp_args[2] = label; + if (execv(ppp, ppp_args) < 0) { + syslog(LOG_ERR, "Could not exec(%s -direct %s). %s (%d)", + ppp, label, strerror(errno), errno); + exit(1); + } +} /* run_ppp */ + +/* Signal handler */ +static void +sighandler(int s) +{ + done = 1; +} /* sighandler */ + +/* Display usage and exit */ +static void +usage(void) +{ + fprintf(stdout, +"Usage: %s options\n" \ +"Where options are:\n" \ +"\t-a bdaddr BDADDR to listen on or connect to (required for client)\n" \ +"\t-c Act as a clinet (default)\n" \ +"\t-C channel RFCOMM channel to listen on or connect to (required)\n" \ +"\t-d Run in foreground\n" \ +"\t-l label Use PPP label (required)\n" \ +"\t-s Act as a server\n" \ +"\t-h Display this message\n", RFCOMM_PPPD); + + exit(255); +} /* usage */ + |