?? hcidump.c
字號:
} } } return fd;}static int open_socket(int dev, unsigned long flags){ struct sockaddr_hci addr; struct hci_filter flt; struct hci_dev_info di; int sk, dd, opt; if (permcheck && dev != HCI_DEV_NONE) { dd = hci_open_dev(dev); if (dd < 0) { perror("Can't open device"); exit(1); } if (hci_devinfo(dev, &di) < 0) { perror("Can't get device info"); exit(1); } opt = hci_test_bit(HCI_RAW, &di.flags); if (ioctl(dd, HCISETRAW, opt) < 0) { if (errno == EACCES) { perror("Can't access device"); exit(1); } } hci_close_dev(dd); } /* Create HCI socket */ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) { perror("Can't create raw socket"); exit(1); } opt = 1; if (setsockopt(sk, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) { perror("Can't enable data direction info"); exit(1); } if (setsockopt(sk, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { perror("Can't enable time stamp"); exit(1); } /* Setup filter */ hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(sk, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("Can't set filter"); exit(1); } /* Bind socket to the HCI device */ addr.hci_family = AF_BLUETOOTH; addr.hci_dev = dev; if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { printf("Can't attach to device hci%d. %s(%d)\n", dev, strerror(errno), errno); exit(1); } return sk;}static int open_connection(in_addr_t addr, in_port_t port){ struct sockaddr_in sa; int sk, opt; sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sk < 0) { perror("Can't create inet socket"); exit(1); } opt = 1; setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(0); if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) { perror("Can't bind inet socket"); close(sk); exit(1); } sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(addr); sa.sin_port = htons(port); if (connect(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) { perror("Can't connect inet socket"); close(sk); exit(1); } return sk;}static int wait_connection(in_addr_t addr, in_port_t port){ struct sockaddr_in sa; struct hostent *host; socklen_t len; int sk, nsk, opt; sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sk < 0) { perror("Can't create inet socket"); exit(1); } opt = 1; setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(addr); sa.sin_port = htons(port); if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) { perror("Can't bind inet socket"); close(sk); exit(1); } host = gethostbyaddr(&sa.sin_addr, sizeof(sa.sin_addr), AF_INET); printf("device: %s:%d snap_len: %d filter: 0x%lx\n", host ? host->h_name : inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), snap_len, filter); if (listen(sk, 1)) { perror("Can't listen on inet socket"); close(sk); exit(1); } len = sizeof(sa); nsk = accept(sk, (struct sockaddr *) &sa, &len); if (nsk < 0) { perror("Can't accept new inet socket"); close(sk); exit(1); } host = gethostbyaddr(&sa.sin_addr, sizeof(sa.sin_addr), AF_INET); printf("device: %s snap_len: %d filter: 0x%lx\n", host ? host->h_name : inet_ntoa(sa.sin_addr), snap_len, filter); close(sk); return nsk;}static struct { char *name; int flag;} filters[] = { { "lmp", FILT_LMP }, { "hci", FILT_HCI }, { "sco", FILT_SCO }, { "l2cap", FILT_L2CAP }, { "rfcomm", FILT_RFCOMM }, { "sdp", FILT_SDP }, { "bnep", FILT_BNEP }, { "cmtp", FILT_CMTP }, { "hidp", FILT_HIDP }, { "hcrp", FILT_HCRP }, { "avdtp", FILT_AVDTP }, { "obex", FILT_OBEX }, { "capi", FILT_CAPI }, { "csr", FILT_CSR }, { "dga", FILT_DGA }, { 0 }};static void parse_filter(int argc, char **argv){ int i,n; for (i = 0; i < argc; i++) { for (n = 0; filters[n].name; n++) { if (!strcasecmp(filters[n].name, argv[i])) { filter |= filters[n].flag; break; } } }}static void usage(void){ printf( "Usage: hcidump [OPTION...] [filter]\n" " -i, --device=hci_dev HCI device\n" " -l, --snap-len=len Snap len (in bytes)\n" " -p, --psm=psm Default PSM\n" " -m, --manufacturer=compid Default manufacturer\n" " -w, --save-dump=file Save dump to a file\n" " -r, --read-dump=file Read dump from a file\n" " -s, --send-dump=host Send dump to a host\n" " -n, --recv-dump=host Receive dump on a host\n" " -t, --ts Display time stamps\n" " -a, --ascii Dump data in ascii\n" " -x, --hex Dump data in hex\n" " -X, --ext Dump data in hex and ascii\n" " -R, --raw Dump raw data\n" " -C, --cmtp=psm PSM for CMTP\n" " -H, --hcrp=psm PSM for HCRP\n" " -O, --obex=channel Channel for OBEX\n" " -A, --audio=file Extract SCO audio data\n" " -B, --btsnoop Use BTSnoop file format\n" " -V, --verbose Verbose decoding\n" " -Y, --novendor No vendor commands or events\n" " -h, --help Give this help list\n" " --usage Give a short usage message\n" );}static struct option main_options[] = { { "device", 1, 0, 'i' }, { "snap-len", 1, 0, 'l' }, { "psm", 1, 0, 'p' }, { "manufacturer", 1, 0, 'm' }, { "save-dump", 1, 0, 'w' }, { "read-dump", 1, 0, 'r' }, { "send-dump", 1, 0, 's' }, { "recv-dump", 1, 0, 'n' }, { "timestamp", 0, 0, 't' }, { "ascii", 0, 0, 'a' }, { "hex", 0, 0, 'x' }, { "ext", 0, 0, 'X' }, { "raw", 0, 0, 'R' }, { "cmtp", 1, 0, 'C' }, { "hcrp", 1, 0, 'H' }, { "obex", 1, 0, 'O' }, { "audio", 1, 0, 'A' }, { "btsnoop", 0, 0, 'B' }, { "verbose", 0, 0, 'V' }, { "novendor", 0, 0, 'Y' }, { "nopermcheck", 0, 0, 'Z' }, { "help", 0, 0, 'h' }, { 0 }};int main(int argc, char *argv[]){ struct hostent *host; struct in_addr addr; int opt, fd = -1; printf("HCI sniffer - Bluetooth packet analyzer ver %s\n", VERSION); while ((opt=getopt_long(argc, argv, "i:l:p:m:w:r:s:n:taxXRC:H:O:A:BVYZh", main_options, NULL)) != -1) { switch(opt) { case 'i': if (strcasecmp(optarg, "none") && strcasecmp(optarg, "system")) device = atoi(optarg + 3); else device = HCI_DEV_NONE; break; case 'l': snap_len = atoi(optarg); break; case 'p': defpsm = atoi(optarg); break; case 'm': defcompid = atoi(optarg); break; case 'w': mode = WRITE; dump_file = strdup(optarg); break; case 'r': mode = READ; dump_file = strdup(optarg); break; case 's': mode = SEND; host = gethostbyname(optarg); if (host) { bcopy(host->h_addr, &addr, sizeof(struct in_addr)); dump_addr = ntohl(addr.s_addr); dump_port = DEFAULT_PORT; } else { dump_addr = INADDR_LOOPBACK; dump_port = DEFAULT_PORT; } break; case 'n': mode = RECEIVE; host = gethostbyname(optarg); if (host) { bcopy(host->h_addr, &addr, sizeof(struct in_addr)); dump_addr = ntohl(addr.s_addr); dump_port = DEFAULT_PORT; } else { dump_addr = INADDR_LOOPBACK; dump_port = DEFAULT_PORT; } break; case 't': flags |= DUMP_TSTAMP; break; case 'a': flags |= DUMP_ASCII; break; case 'x': flags |= DUMP_HEX; break; case 'X': flags |= DUMP_EXT; break; case 'R': flags |= DUMP_RAW; break; case 'C': set_proto(0, atoi(optarg), 0, SDP_UUID_CMTP); break; case 'H': set_proto(0, atoi(optarg), 0, SDP_UUID_HARDCOPY_CONTROL_CHANNEL); break; case 'O': set_proto(0, 0, atoi(optarg), SDP_UUID_OBEX); break; case 'A': audio_file = strdup(optarg); break; case 'B': flags |= DUMP_BTSNOOP; break; case 'V': flags |= DUMP_VERBOSE; break; case 'Y': flags |= DUMP_NOVENDOR; break; case 'Z': permcheck = 0; break; case 'h': default: usage(); exit(0); } } argc -= optind; argv += optind; optind = 0; if (argc > 0) parse_filter(argc, argv); /* Default settings */ if (!filter) filter = ~0L; if (audio_file) fd = open_file(audio_file, AUDIO, flags); switch (mode) { case PARSE: init_parser(flags, filter, defpsm, defcompid, fd); process_frames(device, open_socket(device, flags), -1, flags); break; case READ: init_parser(flags, filter, defpsm, defcompid, fd); read_dump(open_file(dump_file, mode, flags)); break; case WRITE: process_frames(device, open_socket(device, flags), open_file(dump_file, mode, flags), flags); break; case RECEIVE: init_parser(flags, filter, defpsm, defcompid, fd); read_dump(wait_connection(dump_addr, dump_port)); break; case SEND: process_frames(device, open_socket(device, flags), open_connection(dump_addr, dump_port), flags); break; } return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -