1 /*
2 *
3 * BlueZ - Bluetooth protocol stack for Linux
4 *
5 * Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
6 * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <getopt.h>
36 #include <sys/poll.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <sys/ioctl.h>
40 #include <sys/socket.h>
41
42 #include <bluetooth/bluetooth.h>
43 #include <bluetooth/hci.h>
44 #include <bluetooth/hci_lib.h>
45
46 #include <arpa/inet.h>
47 #include <netinet/in.h>
48 #include <netdb.h>
49
50 #include "parser/parser.h"
51 #include "parser/sdp.h"
52
53 #define SNAP_LEN HCI_MAX_FRAME_SIZE
54 #define DEFAULT_PORT "10839";
55
56 /* Modes */
57 enum {
58 PARSE,
59 READ,
60 WRITE,
61 SERVER,
62 PPPDUMP,
63 AUDIO
64 };
65
66 /* Default options */
67 static int snap_len = SNAP_LEN;
68 static int mode = PARSE;
69 static int permcheck = 1;
70 static char *dump_file = NULL;
71 static char *pppdump_file = NULL;
72 static char *audio_file = NULL;
73 static char *dump_addr;
74 static char *dump_port = DEFAULT_PORT;
75 static int af = AF_UNSPEC;
76
77 struct hcidump_hdr {
78 uint16_t len;
79 uint8_t in;
80 uint8_t pad;
81 uint32_t ts_sec;
82 uint32_t ts_usec;
83 } __attribute__ ((packed));
84 #define HCIDUMP_HDR_SIZE (sizeof(struct hcidump_hdr))
85
86 struct btsnoop_hdr {
87 uint8_t id[8]; /* Identification Pattern */
88 uint32_t version; /* Version Number = 1 */
89 uint32_t type; /* Datalink Type */
90 } __attribute__ ((packed));
91 #define BTSNOOP_HDR_SIZE (sizeof(struct btsnoop_hdr))
92
93 struct btsnoop_pkt {
94 uint32_t size; /* Original Length */
95 uint32_t len; /* Included Length */
96 uint32_t flags; /* Packet Flags */
97 uint32_t drops; /* Cumulative Drops */
98 uint64_t ts; /* Timestamp microseconds */
99 uint8_t data[0]; /* Packet Data */
100 } __attribute__ ((packed));
101 #define BTSNOOP_PKT_SIZE (sizeof(struct btsnoop_pkt))
102
103 static uint8_t btsnoop_id[] = { 0x62, 0x74, 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00 };
104
105 static uint32_t btsnoop_version = 0;
106 static uint32_t btsnoop_type = 0;
107
108 struct pktlog_hdr {
109 uint32_t len;
110 uint64_t ts;
111 uint8_t type;
112 } __attribute__ ((packed));
113 #define PKTLOG_HDR_SIZE (sizeof(struct pktlog_hdr))
114
read_n(int fd,char * buf,int len)115 static inline int read_n(int fd, char *buf, int len)
116 {
117 int t = 0, w;
118
119 while (len > 0) {
120 if ((w = read(fd, buf, len)) < 0) {
121 if (errno == EINTR || errno == EAGAIN)
122 continue;
123 return -1;
124 }
125 if (!w)
126 return 0;
127 len -= w; buf += w; t += w;
128 }
129 return t;
130 }
131
write_n(int fd,char * buf,int len)132 static inline int write_n(int fd, char *buf, int len)
133 {
134 int t = 0, w;
135
136 while (len > 0) {
137 if ((w = write(fd, buf, len)) < 0) {
138 if (errno == EINTR || errno == EAGAIN)
139 continue;
140 return -1;
141 }
142 if (!w)
143 return 0;
144 len -= w; buf += w; t += w;
145 }
146 return t;
147 }
148
process_frames(int dev,int sock,int fd,unsigned long flags)149 static int process_frames(int dev, int sock, int fd, unsigned long flags)
150 {
151 struct cmsghdr *cmsg;
152 struct msghdr msg;
153 struct iovec iv;
154 struct hcidump_hdr *dh;
155 struct btsnoop_pkt *dp;
156 struct frame frm;
157 struct pollfd fds[2];
158 int nfds = 0;
159 char *buf, *ctrl;
160 int len, hdr_size = HCIDUMP_HDR_SIZE;
161
162 if (sock < 0)
163 return -1;
164
165 if (snap_len < SNAP_LEN)
166 snap_len = SNAP_LEN;
167
168 if (flags & DUMP_BTSNOOP)
169 hdr_size = BTSNOOP_PKT_SIZE;
170
171 buf = malloc(snap_len + hdr_size);
172 if (!buf) {
173 perror("Can't allocate data buffer");
174 return -1;
175 }
176
177 dh = (void *) buf;
178 dp = (void *) buf;
179 frm.data = buf + hdr_size;
180
181 ctrl = malloc(100);
182 if (!ctrl) {
183 free(buf);
184 perror("Can't allocate control buffer");
185 return -1;
186 }
187
188 if (dev == HCI_DEV_NONE)
189 printf("system: ");
190 else
191 printf("device: hci%d ", dev);
192
193 printf("snap_len: %d filter: 0x%lx\n", snap_len, parser.filter);
194
195 memset(&msg, 0, sizeof(msg));
196
197 if (mode == SERVER) {
198 struct btsnoop_hdr *hdr = (void *) buf;
199
200 btsnoop_version = 1;
201 btsnoop_type = 1002;
202
203 memcpy(hdr->id, btsnoop_id, sizeof(btsnoop_id));
204 hdr->version = htonl(btsnoop_version);
205 hdr->type = htonl(btsnoop_type);
206
207 printf("btsnoop version: %d datalink type: %d\n",
208 btsnoop_version, btsnoop_type);
209
210 len = write(fd, buf, BTSNOOP_HDR_SIZE);
211 if (len < 0) {
212 perror("Can't create dump header");
213 return -1;
214 }
215
216 if (len != BTSNOOP_HDR_SIZE) {
217 fprintf(stderr, "Header size mismatch\n");
218 return -1;
219 }
220
221 fds[nfds].fd = fd;
222 fds[nfds].events = POLLIN;
223 fds[nfds].revents = 0;
224 nfds++;
225 }
226
227 fds[nfds].fd = sock;
228 fds[nfds].events = POLLIN;
229 fds[nfds].revents = 0;
230 nfds++;
231
232 while (1) {
233 int i, n = poll(fds, nfds, -1);
234 if (n <= 0)
235 continue;
236
237 for (i = 0; i < nfds; i++) {
238 if (fds[i].revents & (POLLHUP | POLLERR | POLLNVAL)) {
239 if (fds[i].fd == sock)
240 printf("device: disconnected\n");
241 else
242 printf("client: disconnect\n");
243 return 0;
244 }
245 }
246
247 if (mode == SERVER) {
248 len = recv(fd, buf, snap_len, MSG_DONTWAIT);
249 if (len == 0) {
250 printf("client: disconnect\n");
251 return 0;
252 }
253 if (len < 0 && errno != EAGAIN && errno != EINTR) {
254 perror("Connection read failure");
255 return -1;
256 }
257 }
258
259 iv.iov_base = frm.data;
260 iv.iov_len = snap_len;
261
262 msg.msg_iov = &iv;
263 msg.msg_iovlen = 1;
264 msg.msg_control = ctrl;
265 msg.msg_controllen = 100;
266
267 len = recvmsg(sock, &msg, MSG_DONTWAIT);
268 if (len < 0) {
269 if (errno == EAGAIN || errno == EINTR)
270 continue;
271 perror("Receive failed");
272 return -1;
273 }
274
275 /* Process control message */
276 frm.data_len = len;
277 frm.dev_id = dev;
278 frm.in = 0;
279 frm.pppdump_fd = parser.pppdump_fd;
280 frm.audio_fd = parser.audio_fd;
281
282 cmsg = CMSG_FIRSTHDR(&msg);
283 while (cmsg) {
284 int dir;
285 switch (cmsg->cmsg_type) {
286 case HCI_CMSG_DIR:
287 memcpy(&dir, CMSG_DATA(cmsg), sizeof(int));
288 frm.in = (uint8_t) dir;
289 break;
290 case HCI_CMSG_TSTAMP:
291 memcpy(&frm.ts, CMSG_DATA(cmsg),
292 sizeof(struct timeval));
293 break;
294 }
295 cmsg = CMSG_NXTHDR(&msg, cmsg);
296 }
297
298 frm.ptr = frm.data;
299 frm.len = frm.data_len;
300
301 switch (mode) {
302 case WRITE:
303 case SERVER:
304 /* Save or send dump */
305 if (flags & DUMP_BTSNOOP) {
306 uint64_t ts;
307 uint8_t pkt_type = ((uint8_t *) frm.data)[0];
308 dp->size = htonl(frm.data_len);
309 dp->len = dp->size;
310 dp->flags = ntohl(frm.in & 0x01);
311 dp->drops = 0;
312 ts = (frm.ts.tv_sec - 946684800ll) * 1000000ll + frm.ts.tv_usec;
313 dp->ts = hton64(ts + 0x00E03AB44A676000ll);
314 if (pkt_type == HCI_COMMAND_PKT ||
315 pkt_type == HCI_EVENT_PKT)
316 dp->flags |= ntohl(0x02);
317 } else {
318 dh->len = htobs(frm.data_len);
319 dh->in = frm.in;
320 dh->ts_sec = htobl(frm.ts.tv_sec);
321 dh->ts_usec = htobl(frm.ts.tv_usec);
322 }
323
324 if (write_n(fd, buf, frm.data_len + hdr_size) < 0) {
325 perror("Write error");
326 return -1;
327 }
328 break;
329
330 default:
331 /* Parse and print */
332 parse(&frm);
333 break;
334 }
335 }
336
337 return 0;
338 }
339
read_dump(int fd)340 static void read_dump(int fd)
341 {
342 struct hcidump_hdr dh;
343 struct btsnoop_pkt dp;
344 struct pktlog_hdr ph;
345 struct frame frm;
346 uint8_t pkt_type;
347 int err;
348
349 frm.data = malloc(HCI_MAX_FRAME_SIZE);
350 if (!frm.data) {
351 perror("Can't allocate data buffer");
352 exit(1);
353 }
354
355 while (1) {
356 if (parser.flags & DUMP_PKTLOG)
357 err = read_n(fd, (void *) &ph, PKTLOG_HDR_SIZE);
358 else if (parser.flags & DUMP_BTSNOOP)
359 err = read_n(fd, (void *) &dp, BTSNOOP_PKT_SIZE);
360 else
361 err = read_n(fd, (void *) &dh, HCIDUMP_HDR_SIZE);
362
363 if (err < 0)
364 goto failed;
365 if (!err)
366 return;
367
368 if (parser.flags & DUMP_PKTLOG) {
369 switch (ph.type) {
370 case 0x00:
371 ((uint8_t *) frm.data)[0] = HCI_COMMAND_PKT;
372 frm.in = 0;
373 break;
374 case 0x01:
375 ((uint8_t *) frm.data)[0] = HCI_EVENT_PKT;
376 frm.in = 1;
377 break;
378 case 0x02:
379 ((uint8_t *) frm.data)[0] = HCI_ACLDATA_PKT;
380 frm.in = 0;
381 break;
382 case 0x03:
383 ((uint8_t *) frm.data)[0] = HCI_ACLDATA_PKT;
384 frm.in = 1;
385 break;
386 default:
387 lseek(fd, ntohl(ph.len) - 9, SEEK_CUR);
388 continue;
389 }
390
391 frm.data_len = ntohl(ph.len) - 8;
392 err = read_n(fd, frm.data + 1, frm.data_len - 1);
393 } else if (parser.flags & DUMP_BTSNOOP) {
394 switch (btsnoop_type) {
395 case 1001:
396 if (ntohl(dp.flags) & 0x02) {
397 if (ntohl(dp.flags) & 0x01)
398 pkt_type = HCI_EVENT_PKT;
399 else
400 pkt_type = HCI_COMMAND_PKT;
401 } else
402 pkt_type = HCI_ACLDATA_PKT;
403
404 ((uint8_t *) frm.data)[0] = pkt_type;
405
406 frm.data_len = ntohl(dp.len) + 1;
407 err = read_n(fd, frm.data + 1, frm.data_len - 1);
408 break;
409
410 case 1002:
411 frm.data_len = ntohl(dp.len);
412 err = read_n(fd, frm.data, frm.data_len);
413 break;
414 }
415 } else {
416 frm.data_len = btohs(dh.len);
417 err = read_n(fd, frm.data, frm.data_len);
418 }
419
420 if (err < 0)
421 goto failed;
422 if (!err)
423 return;
424
425 frm.ptr = frm.data;
426 frm.len = frm.data_len;
427
428 if (parser.flags & DUMP_PKTLOG) {
429 uint64_t ts;
430 ts = ntoh64(ph.ts);
431 frm.ts.tv_sec = ts >> 32;
432 frm.ts.tv_usec = ts & 0xffffffff;
433 } else if (parser.flags & DUMP_BTSNOOP) {
434 uint64_t ts;
435 frm.in = ntohl(dp.flags) & 0x01;
436 ts = ntoh64(dp.ts) - 0x00E03AB44A676000ll;
437 frm.ts.tv_sec = (ts / 1000000ll) + 946684800ll;
438 frm.ts.tv_usec = ts % 1000000ll;
439 } else {
440 frm.in = dh.in;
441 frm.ts.tv_sec = btohl(dh.ts_sec);
442 frm.ts.tv_usec = btohl(dh.ts_usec);
443 }
444
445 parse(&frm);
446 }
447
448 failed:
449 perror("Read failed");
450 exit(1);
451 }
452
open_file(char * file,int mode,unsigned long flags)453 static int open_file(char *file, int mode, unsigned long flags)
454 {
455 unsigned char buf[BTSNOOP_HDR_SIZE];
456 struct btsnoop_hdr *hdr = (struct btsnoop_hdr *) buf;
457 int fd, len, open_flags;
458
459 if (mode == WRITE || mode == PPPDUMP || mode == AUDIO)
460 open_flags = O_WRONLY | O_CREAT | O_TRUNC;
461 else
462 open_flags = O_RDONLY;
463
464 fd = open(file, open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
465 if (fd < 0) {
466 perror("Can't open dump file");
467 exit(1);
468 }
469
470 if (mode == READ) {
471 len = read(fd, buf, BTSNOOP_HDR_SIZE);
472 if (len != BTSNOOP_HDR_SIZE) {
473 lseek(fd, 0, SEEK_SET);
474 return fd;
475 }
476
477 if (!memcmp(hdr->id, btsnoop_id, sizeof(btsnoop_id))) {
478 parser.flags |= DUMP_BTSNOOP;
479
480 btsnoop_version = ntohl(hdr->version);
481 btsnoop_type = ntohl(hdr->type);
482
483 printf("btsnoop version: %d datalink type: %d\n",
484 btsnoop_version, btsnoop_type);
485
486 if (btsnoop_version != 1) {
487 fprintf(stderr, "Unsupported BTSnoop version\n");
488 exit(1);
489 }
490
491 if (btsnoop_type != 1001 && btsnoop_type != 1002) {
492 fprintf(stderr, "Unsupported BTSnoop datalink type\n");
493 exit(1);
494 }
495 } else {
496 if (buf[0] == 0x00 && buf[1] == 0x00) {
497 parser.flags |= DUMP_PKTLOG;
498 printf("packet logger data format\n");
499 }
500
501 parser.flags &= ~DUMP_BTSNOOP;
502 lseek(fd, 0, SEEK_SET);
503 return fd;
504 }
505 } else {
506 if (flags & DUMP_BTSNOOP) {
507 btsnoop_version = 1;
508 btsnoop_type = 1002;
509
510 memcpy(hdr->id, btsnoop_id, sizeof(btsnoop_id));
511 hdr->version = htonl(btsnoop_version);
512 hdr->type = htonl(btsnoop_type);
513
514 printf("btsnoop version: %d datalink type: %d\n",
515 btsnoop_version, btsnoop_type);
516
517 len = write(fd, buf, BTSNOOP_HDR_SIZE);
518 if (len < 0) {
519 perror("Can't create dump header");
520 exit(1);
521 }
522
523 if (len != BTSNOOP_HDR_SIZE) {
524 fprintf(stderr, "Header size mismatch\n");
525 exit(1);
526 }
527 }
528 }
529
530 return fd;
531 }
532
open_socket(int dev,unsigned long flags)533 static int open_socket(int dev, unsigned long flags)
534 {
535 struct sockaddr_hci addr;
536 struct hci_filter flt;
537 struct hci_dev_info di;
538 int sk, dd, opt;
539
540 if (permcheck && dev != HCI_DEV_NONE) {
541 dd = hci_open_dev(dev);
542 if (dd < 0) {
543 perror("Can't open device");
544 return -1;
545 }
546
547 if (hci_devinfo(dev, &di) < 0) {
548 perror("Can't get device info");
549 return -1;
550 }
551
552 opt = hci_test_bit(HCI_RAW, &di.flags);
553 if (ioctl(dd, HCISETRAW, opt) < 0) {
554 if (errno == EACCES) {
555 perror("Can't access device");
556 return -1;
557 }
558 }
559
560 hci_close_dev(dd);
561 }
562
563 /* Create HCI socket */
564 sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
565 if (sk < 0) {
566 perror("Can't create raw socket");
567 return -1;
568 }
569
570 opt = 1;
571 if (setsockopt(sk, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
572 perror("Can't enable data direction info");
573 return -1;
574 }
575
576 opt = 1;
577 if (setsockopt(sk, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
578 perror("Can't enable time stamp");
579 return -1;
580 }
581
582 /* Setup filter */
583 hci_filter_clear(&flt);
584 hci_filter_all_ptypes(&flt);
585 hci_filter_all_events(&flt);
586 if (setsockopt(sk, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
587 perror("Can't set filter");
588 return -1;
589 }
590
591 /* Bind socket to the HCI device */
592 memset(&addr, 0, sizeof(addr));
593 addr.hci_family = AF_BLUETOOTH;
594 addr.hci_dev = dev;
595 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
596 printf("Can't attach to device hci%d. %s(%d)\n",
597 dev, strerror(errno), errno);
598 return -1;
599 }
600
601 return sk;
602 }
603
create_datagram(unsigned short port)604 static int create_datagram(unsigned short port)
605 {
606 struct sockaddr_in addr;
607 int sk, opt = 1;
608
609 sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
610 if (sk < 0)
611 return -1;
612
613 if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
614 close(sk);
615 return -1;
616 }
617
618 memset(&addr, 0, sizeof(addr));
619 addr.sin_family = AF_INET;
620 addr.sin_port = htons(port);
621 addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
622
623 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
624 close(sk);
625 return -1;
626 }
627
628 return sk;
629 }
630
631 static unsigned char ping_data[] = { 'p', 'i', 'n', 'g' };
632 static unsigned char pong_data[] = { 'p', 'o', 'n', 'g' };
633
handle_datagram(int sk)634 static void handle_datagram(int sk)
635 {
636 struct sockaddr_in addr;
637 socklen_t addr_len = sizeof(addr);
638 unsigned char buf[64];
639 ssize_t len;
640
641 len = recvfrom(sk, buf, sizeof(buf), MSG_DONTWAIT,
642 (struct sockaddr *) &addr, &addr_len);
643
644 if (len != sizeof(ping_data))
645 return;
646
647 if (memcmp(buf, ping_data, sizeof(ping_data)) != 0)
648 return;
649
650 len = sendto(sk, pong_data, sizeof(pong_data), 0,
651 (struct sockaddr *) &addr, sizeof(addr));
652 }
653
wait_connection(char * addr,char * port)654 static int wait_connection(char *addr, char *port)
655 {
656 char hname[100], hport[10];
657 struct addrinfo *ai, *runp;
658 struct addrinfo hints;
659 struct pollfd fds[3];
660 unsigned int nfds = 0;
661 int err, opt, datagram;
662
663 memset(&hints, 0, sizeof (hints));
664 hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
665 hints.ai_socktype = SOCK_STREAM;
666 hints.ai_protocol = IPPROTO_TCP;
667
668 err = getaddrinfo(dump_addr, dump_port, &hints, &ai);
669 if (err < 0) {
670 printf("Can't get address info: %s\n", gai_strerror(err));
671 return -1;
672 }
673
674 runp = ai;
675
676 datagram = create_datagram(atoi(dump_port));
677 if (datagram < 0) {
678 printf("server: no discover protocol\n");
679 } else {
680 fds[nfds].fd = datagram;
681 fds[nfds].events = POLLIN;
682 nfds++;
683 }
684
685 while (runp != NULL && nfds < sizeof(fds) / sizeof(fds[0])) {
686 fds[nfds].fd = socket(runp->ai_family, runp->ai_socktype,
687 runp->ai_protocol);
688 if (fds[nfds].fd < 0) {
689 perror("Can't create socket");
690 return -1;
691 }
692
693 fds[nfds].events = POLLIN;
694
695 opt = 1;
696 setsockopt(fds[nfds].fd, SOL_SOCKET, SO_REUSEADDR,
697 &opt, sizeof(opt));
698
699 opt = 0;
700 setsockopt(fds[nfds].fd, SOL_SOCKET, SO_KEEPALIVE,
701 &opt, sizeof(opt));
702
703 if (bind(fds[nfds].fd, runp->ai_addr, runp->ai_addrlen) < 0) {
704 if (errno != EADDRINUSE) {
705 perror("Can't bind socket");
706 return -1;
707 }
708
709 close(fds[nfds].fd);
710 } else {
711 if (listen(fds[nfds].fd, SOMAXCONN) < 0) {
712 perror("Can't listen on socket");
713 return -1;
714 }
715
716 getnameinfo(runp->ai_addr, runp->ai_addrlen,
717 hname, sizeof(hname),
718 hport, sizeof(hport),
719 NI_NUMERICSERV);
720
721 printf("server: %s:%s snap_len: %d filter: 0x%lx\n",
722 hname, hport, snap_len, parser.filter);
723
724 nfds++;
725 }
726
727 runp = runp->ai_next;
728 }
729
730 freeaddrinfo(ai);
731
732 while (1) {
733 unsigned int i;
734 int n = poll(fds, nfds, -1);
735 if (n <= 0)
736 continue;
737
738 for (i = 0; i < nfds; i++) {
739 struct sockaddr_storage rem;
740 socklen_t remlen = sizeof(rem);
741 int sk;
742
743 if (!(fds[i].revents & POLLIN))
744 continue;
745
746 if (fds[i].fd == datagram) {
747 handle_datagram(datagram);
748 continue;
749 }
750
751 sk = accept(fds[i].fd, (struct sockaddr *) &rem, &remlen);
752 if (sk < 0)
753 continue;
754
755 getnameinfo((struct sockaddr *) &rem, remlen,
756 hname, sizeof(hname),
757 hport, sizeof(hport),
758 NI_NUMERICSERV);
759
760 printf("client: %s:%s snap_len: %d filter: 0x%lx\n",
761 hname, hport, snap_len, parser.filter);
762
763 for (n = 0; n < (int) nfds; n++)
764 close(fds[n].fd);
765
766 return sk;
767 }
768 }
769
770 return -1;
771 }
772
run_server(int dev,char * addr,char * port,unsigned long flags)773 static int run_server(int dev, char *addr, char *port, unsigned long flags)
774 {
775 while (1) {
776 int dd, sk;
777
778 sk = wait_connection(addr, port);
779 if (sk < 0)
780 continue;
781
782 //fcntl(sk, F_SETFL, O_NONBLOCK);
783
784 dd = open_socket(dev, flags);
785 if (dd < 0) {
786 close(sk);
787 continue;
788 }
789
790 process_frames(dev, dd, sk, flags);
791
792 close(dd);
793 close(sk);
794 }
795
796 return 0;
797 }
798
799 static struct {
800 char *name;
801 int flag;
802 } filters[] = {
803 { "lmp", FILT_LMP },
804 { "hci", FILT_HCI },
805 { "sco", FILT_SCO },
806 { "l2cap", FILT_L2CAP },
807 { "rfcomm", FILT_RFCOMM },
808 { "sdp", FILT_SDP },
809 { "bnep", FILT_BNEP },
810 { "cmtp", FILT_CMTP },
811 { "hidp", FILT_HIDP },
812 { "hcrp", FILT_HCRP },
813 { "att", FILT_ATT },
814 { "avdtp", FILT_AVDTP },
815 { "avctp", FILT_AVCTP },
816 { "obex", FILT_OBEX },
817 { "capi", FILT_CAPI },
818 { "ppp", FILT_PPP },
819 { "csr", FILT_CSR },
820 { "dga", FILT_DGA },
821 { 0 }
822 };
823
parse_filter(int argc,char ** argv)824 static unsigned long parse_filter(int argc, char **argv)
825 {
826 unsigned long filter = 0;
827 int i,n;
828
829 for (i = 0; i < argc; i++) {
830 for (n = 0; filters[n].name; n++) {
831 if (!strcasecmp(filters[n].name, argv[i])) {
832 filter |= filters[n].flag;
833 break;
834 }
835 }
836 }
837
838 return filter;
839 }
840
usage(void)841 static void usage(void)
842 {
843 printf(
844 "Usage: hcidump [OPTION...] [filter]\n"
845 " -i, --device=hci_dev HCI device\n"
846 " -l, --snap-len=len Snap len (in bytes)\n"
847 " -p, --psm=psm Default PSM\n"
848 " -m, --manufacturer=compid Default manufacturer\n"
849 " -w, --save-dump=file Save dump to a file\n"
850 " -r, --read-dump=file Read dump from a file\n"
851 " -d, --wait-dump=host Wait on a host and send\n"
852 " -t, --ts Display time stamps\n"
853 " -a, --ascii Dump data in ascii\n"
854 " -x, --hex Dump data in hex\n"
855 " -X, --ext Dump data in hex and ascii\n"
856 " -R, --raw Dump raw data\n"
857 " -C, --cmtp=psm PSM for CMTP\n"
858 " -H, --hcrp=psm PSM for HCRP\n"
859 " -O, --obex=channel Channel for OBEX\n"
860 " -P, --ppp=channel Channel for PPP\n"
861 " -D, --pppdump=file Extract PPP traffic\n"
862 " -A, --audio=file Extract SCO audio data\n"
863 " -Y, --novendor No vendor commands or events\n"
864 " -4, --ipv4 Use IPv4 as transport\n"
865 " -6 --ipv6 Use IPv6 as transport\n"
866 " -h, --help Give this help list\n"
867 " -v, --version Give version information\n"
868 " --usage Give a short usage message\n"
869 );
870 }
871
872 static struct option main_options[] = {
873 { "device", 1, 0, 'i' },
874 { "snap-len", 1, 0, 'l' },
875 { "psm", 1, 0, 'p' },
876 { "manufacturer", 1, 0, 'm' },
877 { "save-dump", 1, 0, 'w' },
878 { "read-dump", 1, 0, 'r' },
879 { "wait-dump", 1, 0, 'd' },
880 { "timestamp", 0, 0, 't' },
881 { "ascii", 0, 0, 'a' },
882 { "hex", 0, 0, 'x' },
883 { "ext", 0, 0, 'X' },
884 { "raw", 0, 0, 'R' },
885 { "cmtp", 1, 0, 'C' },
886 { "hcrp", 1, 0, 'H' },
887 { "obex", 1, 0, 'O' },
888 { "ppp", 1, 0, 'P' },
889 { "pppdump", 1, 0, 'D' },
890 { "audio", 1, 0, 'A' },
891 { "novendor", 0, 0, 'Y' },
892 { "nopermcheck", 0, 0, 'Z' },
893 { "ipv4", 0, 0, '4' },
894 { "ipv6", 0, 0, '6' },
895 { "help", 0, 0, 'h' },
896 { "version", 0, 0, 'v' },
897 { 0 }
898 };
899
main(int argc,char * argv[])900 int main(int argc, char *argv[])
901 {
902 unsigned long flags = 0;
903 unsigned long filter = 0;
904 int device = 0;
905 int defpsm = 0;
906 int defcompid = DEFAULT_COMPID;
907 int opt, pppdump_fd = -1, audio_fd = -1;
908
909 while ((opt=getopt_long(argc, argv, "i:l:p:m:w:r:d:taxXRC:H:O:P:D:A:YZ46hv", main_options, NULL)) != -1) {
910 switch(opt) {
911 case 'i':
912 if (strcasecmp(optarg, "none") && strcasecmp(optarg, "system"))
913 device = atoi(optarg + 3);
914 else
915 device = HCI_DEV_NONE;
916 break;
917
918 case 'l':
919 snap_len = atoi(optarg);
920 break;
921
922 case 'p':
923 defpsm = atoi(optarg);
924 break;
925
926 case 'm':
927 defcompid = atoi(optarg);
928 break;
929
930 case 'w':
931 mode = WRITE;
932 dump_file = strdup(optarg);
933 break;
934
935 case 'r':
936 mode = READ;
937 dump_file = strdup(optarg);
938 break;
939
940 case 'd':
941 mode = SERVER;
942 dump_addr = optarg;
943 break;
944
945 case 't':
946 flags |= DUMP_TSTAMP;
947 break;
948
949 case 'a':
950 flags |= DUMP_ASCII;
951 break;
952
953 case 'x':
954 flags |= DUMP_HEX;
955 break;
956
957 case 'X':
958 flags |= DUMP_EXT;
959 break;
960
961 case 'R':
962 flags |= DUMP_RAW;
963 break;
964
965 case 'C':
966 set_proto(0, atoi(optarg), 0, SDP_UUID_CMTP);
967 break;
968
969 case 'H':
970 set_proto(0, atoi(optarg), 0, SDP_UUID_HARDCOPY_CONTROL_CHANNEL);
971 break;
972
973 case 'O':
974 set_proto(0, 0, atoi(optarg), SDP_UUID_OBEX);
975 break;
976
977 case 'P':
978 set_proto(0, 0, atoi(optarg), SDP_UUID_LAN_ACCESS_PPP);
979 break;
980
981 case 'D':
982 pppdump_file = strdup(optarg);
983 break;
984
985 case 'A':
986 audio_file = strdup(optarg);
987 break;
988
989 case 'Y':
990 flags |= DUMP_NOVENDOR;
991 break;
992
993 case 'Z':
994 permcheck = 0;
995 break;
996
997 case '4':
998 af = AF_INET;
999 break;
1000
1001 case '6':
1002 af = AF_INET6;
1003 break;
1004
1005 case 'v':
1006 printf("%s\n", VERSION);
1007 exit(0);
1008
1009 case 'h':
1010 default:
1011 usage();
1012 exit(0);
1013 }
1014 }
1015
1016 argc -= optind;
1017 argv += optind;
1018 optind = 0;
1019
1020 printf("HCI sniffer - Bluetooth packet analyzer ver %s\n", VERSION);
1021
1022 if (argc > 0)
1023 filter = parse_filter(argc, argv);
1024
1025 /* Default settings */
1026 if (!filter)
1027 filter = ~0L;
1028
1029 if (pppdump_file)
1030 pppdump_fd = open_file(pppdump_file, PPPDUMP, flags);
1031
1032 if (audio_file)
1033 audio_fd = open_file(audio_file, AUDIO, flags);
1034
1035 switch (mode) {
1036 case PARSE:
1037 flags |= DUMP_VERBOSE;
1038 init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
1039 process_frames(device, open_socket(device, flags), -1, flags);
1040 break;
1041
1042 case READ:
1043 flags |= DUMP_VERBOSE;
1044 init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
1045 read_dump(open_file(dump_file, mode, flags));
1046 break;
1047
1048 case WRITE:
1049 flags |= DUMP_BTSNOOP;
1050 process_frames(device, open_socket(device, flags),
1051 open_file(dump_file, mode, flags), flags);
1052 break;
1053
1054 case SERVER:
1055 flags |= DUMP_BTSNOOP;
1056 init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
1057 run_server(device, dump_addr, dump_port, flags);
1058 break;
1059 }
1060
1061 return 0;
1062 }
1063