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