1 /* $NetBSD: btkey.c,v 1.2 2008/07/21 14:19:21 lukem Exp $ */
4 * Copyright (c) 2007 Iain Hibbert
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/cdefs.h>
31 __COPYRIGHT("@(#) Copyright (c) 2007 Iain Hibbert. All rights reserved.");
32 __RCSID("$NetBSD: btkey.c,v 1.2 2008/07/21 14:19:21 lukem Exp $");
34 #include <bluetooth.h>
45 static void usage(void);
46 static bool scan_key(const char *);
50 uint8_t key
[HCI_KEY_SIZE
];
53 main(int ac
, char *av
[])
57 bool cf
, cd
, lf
, ld
, rf
, rd
, wf
, wd
, nk
;
59 memset(&laddr
, 0, sizeof(laddr
));
60 memset(&raddr
, 0, sizeof(raddr
));
61 memset(key
, 0, sizeof(key
));
62 cf
= cd
= lf
= ld
= rf
= rd
= wf
= wd
= nk
= false;
64 while ((ch
= getopt(ac
, av
, "a:cCd:k:lLrRwW")) != EOF
) {
66 case 'a': /* remote device address */
67 if (!bt_aton(optarg
, &raddr
)) {
68 he
= bt_gethostbyname(optarg
);
70 errx(EXIT_FAILURE
, "%s: %s",
71 optarg
, hstrerror(h_errno
));
73 bdaddr_copy(&raddr
, (bdaddr_t
*)he
->h_addr
);
77 case 'c': /* clear from file */
81 case 'C': /* clear from device */
85 case 'd': /* local device address */
86 if (!bt_devaddr(optarg
, &laddr
)
87 && !bt_aton(optarg
, &laddr
)) {
88 he
= bt_gethostbyname(optarg
);
90 errx(EXIT_FAILURE
, "%s: %s",
91 optarg
, hstrerror(h_errno
));
93 bdaddr_copy(&laddr
, (bdaddr_t
*)he
->h_addr
);
97 case 'k': /* new link key */
98 if (!scan_key(optarg
))
99 errx(EXIT_FAILURE
, "invalid key '%s'", optarg
);
104 case 'l': /* list from file */
108 case 'L': /* list from device */
112 case 'r': /* read from file */
116 case 'R': /* read from device */
120 case 'w': /* write to file */
124 case 'W': /* write to device */
139 if ((lf
|| ld
) && (rf
|| rd
|| wf
|| wd
|| cf
|| cd
|| nk
))
140 errx(EXIT_FAILURE
, "list is exclusive of other options");
142 if (((rf
&& rd
) || (rf
&& nk
) || (rd
&& nk
)) && (wf
|| wd
))
143 errx(EXIT_FAILURE
, "too many key sources");
145 if (((bdaddr_any(&laddr
) || bdaddr_any(&raddr
)) && !(lf
|| ld
))
146 || ((lf
|| ld
) && (bdaddr_any(&laddr
) || !bdaddr_any(&raddr
)))
151 * do what we gotta do and be done
153 if (!bdaddr_any(&laddr
))
154 print_addr("device", &laddr
);
156 if (!bdaddr_any(&raddr
))
157 print_addr("bdaddr", &raddr
);
159 if (lf
&& !list_file())
160 err(EXIT_FAILURE
, "list file");
162 if (ld
&& !list_device())
163 err(EXIT_FAILURE
, "list device");
166 print_key("new key", key
);
170 err(EXIT_FAILURE
, "file key");
172 print_key("file key", key
);
177 err(EXIT_FAILURE
, "device key");
179 print_key("device key", key
);
182 if (wf
|| wd
|| cf
|| cd
)
187 err(EXIT_FAILURE
, "write to file");
189 printf("written to file\n");
194 err(EXIT_FAILURE
, "write to device");
196 printf("written to device\n");
201 err(EXIT_FAILURE
, "clear from file");
203 printf("cleared from file\n");
208 err(EXIT_FAILURE
, "clear from device");
210 printf("cleared from device\n");
221 "Usage: %s [-cCrRwW] [-k key] -a address -d device\n"
222 " %s -lL -d device\n"
223 "\n", getprogname(), getprogname());
227 "\t-a address remote device address\n"
228 "\t-c clear from file\n"
229 "\t-C clear from device\n"
230 "\t-d device local device address\n"
231 "\t-k key user specified link_key\n"
232 "\t-l list file keys\n"
233 "\t-L list device keys\n"
234 "\t-r read from file\n"
235 "\t-R read from device\n"
236 "\t-w write to file\n"
237 "\t-W write to device\n"
244 scan_key(const char *arg
)
246 static const char digits
[] = "0123456789abcdef";
250 memset(key
, 0, sizeof(key
));
252 for (i
= 0 ; i
< HCI_KEY_SIZE
; i
++) {
253 for (j
= 0 ; j
< 2 ; j
++) {
257 for (p
= digits
; *p
!= tolower((int)*arg
) ; p
++)
262 key
[i
] = (key
[i
] << 4) + (p
- digits
);
273 print_key(const char *type
, const uint8_t *src
)
277 printf("%10s: ", type
);
278 for (i
= 0 ; i
< HCI_KEY_SIZE
; i
++)
279 printf("%2.2x", src
[i
]);
286 print_addr(const char *type
, const bdaddr_t
*addr
)
288 char name
[HCI_DEVNAME_SIZE
];
291 printf("%10s: %s", type
, bt_ntoa(addr
, NULL
));
293 if (bt_devname(name
, addr
))
294 printf(" (%s)", name
);
295 else if ((he
= bt_gethostbyaddr((const char *)addr
,
296 sizeof(bdaddr_t
), AF_BLUETOOTH
)) != NULL
)
297 printf(" (%s)", he
->h_name
);