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