1 /* $NetBSD: btpin.c,v 1.3 2007/04/14 09:28:39 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/types.h> 35 #include <sys/un.h> 36 #include <bluetooth.h> 37 #include <err.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <time.h> 41 #include <unistd.h> 42 43 void usage(void); 44 45 int 46 main(int ac, char *av[]) 47 { 48 bthcid_pin_response_t rp; 49 struct sockaddr_un un; 50 char *pin = NULL; 51 int ch, s, len; 52 53 memset(&rp, 0, sizeof(rp)); 54 len = -1; 55 56 memset(&un, 0, sizeof(un)); 57 un.sun_len = sizeof(un); 58 un.sun_family = AF_LOCAL; 59 strlcpy(un.sun_path, BTHCID_SOCKET_NAME, sizeof(un.sun_path)); 60 61 while ((ch = getopt(ac, av, "a:d:l:p:rs:")) != -1) { 62 switch (ch) { 63 case 'a': 64 if (!bt_aton(optarg, &rp.raddr)) { 65 struct hostent *he = NULL; 66 67 if ((he = bt_gethostbyname(optarg)) == NULL) 68 errx(EXIT_FAILURE, "%s: %s", optarg, 69 hstrerror(h_errno)); 70 71 bdaddr_copy(&rp.raddr, (bdaddr_t *)he->h_addr); 72 } 73 break; 74 75 case 'd': 76 if (!bt_devaddr(optarg, &rp.laddr)) 77 err(EXIT_FAILURE, "%s", optarg); 78 79 break; 80 81 case 'l': 82 len = atoi(optarg); 83 if (len < 1 || len > HCI_PIN_SIZE) 84 errx(EXIT_FAILURE, "Invalid PIN length"); 85 86 break; 87 88 case 'p': 89 pin = optarg; 90 break; 91 92 case 'r': 93 if (len == -1) 94 len = 4; 95 96 break; 97 98 case 's': 99 strlcpy(un.sun_path, optarg, sizeof(un.sun_path)); 100 break; 101 102 default: 103 usage(); 104 } 105 } 106 107 if (bdaddr_any(&rp.raddr)) 108 usage(); 109 110 if (pin == NULL) { 111 if (len == -1) 112 usage(); 113 114 srandom(time(NULL)); 115 116 pin = (char *)rp.pin; 117 while (len-- > 0) 118 *pin++ = '0' + (random() % 10); 119 120 printf("PIN: %.*s\n", HCI_PIN_SIZE, rp.pin); 121 } else { 122 if (len != -1) 123 usage(); 124 125 strncpy((char *)rp.pin, pin, HCI_PIN_SIZE); 126 } 127 128 s = socket(PF_LOCAL, SOCK_STREAM, 0); 129 if (s < 0) 130 err(EXIT_FAILURE, "socket"); 131 132 if (connect(s, (struct sockaddr *)&un, sizeof(un)) < 0) 133 err(EXIT_FAILURE, "connect(\"%s\")", un.sun_path); 134 135 if (send(s, &rp, sizeof(rp), 0) != sizeof(rp)) 136 err(EXIT_FAILURE, "send"); 137 138 close(s); 139 exit(EXIT_SUCCESS); 140 } 141 142 void 143 usage(void) 144 { 145 146 fprintf(stderr, 147 "usage: %s [-d device] [-s socket] {-p pin | -r [-l len]} -a addr\n" 148 "", getprogname()); 149 150 exit(EXIT_FAILURE); 151 } 152