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