1 /* $NetBSD: btpin.c,v 1.2 2006/09/26 19:18:19 plunky Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Itronix Inc. 5 * All rights reserved. 6 * 7 * Written by Iain Hibbert for Itronix Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of Itronix Inc. may not be used to endorse 18 * or promote products derived from this software without specific 19 * prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __COPYRIGHT("@(#) Copyright (c) 2006 Itronix, Inc\n" 36 "All rights reserved.\n"); 37 __RCSID("$NetBSD: btpin.c,v 1.2 2006/09/26 19:18:19 plunky Exp $"); 38 39 #include <sys/types.h> 40 #include <sys/un.h> 41 #include <bluetooth.h> 42 #include <err.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <time.h> 46 #include <unistd.h> 47 48 int main(int, char *[]); 49 void usage(void); 50 51 int 52 main(int ac, char *av[]) 53 { 54 bthcid_pin_response_t rp; 55 struct sockaddr_un un; 56 char *pin = NULL; 57 int ch, s, len; 58 59 memset(&rp, 0, sizeof(rp)); 60 len = -1; 61 62 memset(&un, 0, sizeof(un)); 63 un.sun_len = sizeof(un); 64 un.sun_family = AF_LOCAL; 65 strlcpy(un.sun_path, BTHCID_SOCKET_NAME, sizeof(un.sun_path)); 66 67 while ((ch = getopt(ac, av, "a:d:l:p:rs:")) != EOF) { 68 switch (ch) { 69 case 'a': 70 if (!bt_aton(optarg, &rp.raddr)) { 71 struct hostent *he = NULL; 72 73 if ((he = bt_gethostbyname(optarg)) == NULL) 74 errx(EXIT_FAILURE, "%s: %s", optarg, 75 hstrerror(h_errno)); 76 77 bdaddr_copy(&rp.raddr, (bdaddr_t *)he->h_addr); 78 } 79 break; 80 81 case 'd': 82 if (!bt_devaddr(optarg, &rp.laddr)) 83 err(EXIT_FAILURE, "%s", optarg); 84 85 break; 86 87 case 'l': 88 len = atoi(optarg); 89 if (len < 1 || len > HCI_PIN_SIZE) 90 errx(EXIT_FAILURE, "Invalid PIN length"); 91 92 break; 93 94 case 'p': 95 pin = optarg; 96 break; 97 98 case 'r': 99 if (len == -1) 100 len = 4; 101 102 break; 103 104 case 's': 105 strlcpy(un.sun_path, optarg, sizeof(un.sun_path)); 106 break; 107 108 default: 109 usage(); 110 } 111 } 112 113 if (bdaddr_any(&rp.raddr)) 114 usage(); 115 116 if (pin == NULL) { 117 if (len == -1) 118 usage(); 119 120 srandom(time(NULL)); 121 122 pin = (char *)rp.pin; 123 while (len-- > 0) 124 *pin++ = '0' + (random() % 10); 125 126 printf("PIN: %.*s\n", HCI_PIN_SIZE, rp.pin); 127 } else { 128 if (len != -1) 129 usage(); 130 131 strncpy((char *)rp.pin, pin, HCI_PIN_SIZE); 132 } 133 134 s = socket(PF_LOCAL, SOCK_STREAM, 0); 135 if (s < 0) 136 err(EXIT_FAILURE, "socket"); 137 138 if (connect(s, (struct sockaddr *)&un, sizeof(un)) < 0) 139 err(EXIT_FAILURE, "connect(\"%s\")", un.sun_path); 140 141 if (send(s, &rp, sizeof(rp), 0) != sizeof(rp)) 142 err(EXIT_FAILURE, "send"); 143 144 close(s); 145 exit(EXIT_SUCCESS); 146 } 147 148 void 149 usage(void) 150 { 151 152 fprintf(stderr, 153 "usage: %s [-d device] [-s socket] [-p pin | -r [-l len]] -a addr\n" 154 "", getprogname()); 155 156 exit(EXIT_FAILURE); 157 } 158