1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2000-2002 Maxim Krasnyansky <maxk (at) qualcomm.com> 6 * Copyright (C) 2003-2011 Marcel Holtmann <marcel (at) 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 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 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 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 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 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 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 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 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 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 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 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 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 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