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