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