hcidump.c revision 0acc29e48dbb65c22a7aa4e6d20ebe30275a763a
1/*
2	HCIDump - HCI packet analyzer
3	Copyright (C) 2000-2001 Maxim Krasnyansky <maxk@qualcomm.com>
4
5	This program is free software; you can redistribute it and/or modify
6	it under the terms of the GNU General Public License version 2 as
7	published by the Free Software Foundation;
8
9	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12	IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM,
13	OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
14	RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15	NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
16	USE OR PERFORMANCE OF THIS SOFTWARE.
17
18	ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS,
19	TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED.
20*/
21
22/*
23 * $Id$
24 */
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <unistd.h>
29#include <termios.h>
30#include <fcntl.h>
31#include <sys/ioctl.h>
32#include <sys/socket.h>
33#include <sys/types.h>
34#include <sys/uio.h>
35#include <errno.h>
36#include <string.h>
37
38#include <asm/types.h>
39
40#include <bluetooth/bluetooth.h>
41#include <bluetooth/hci.h>
42#include <bluetooth/l2cap.h>
43
44#include "parser.h"
45
46/* Default options */
47#define SNAP_LEN (1 + HCI_ACL_HDR_SIZE + L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + 60)
48int snap_len = SNAP_LEN;
49
50void usage(void)
51{
52	printf("HCIDump - HCI packet analyzer ver %s\n", VERSION);
53	printf("Usage:\n");
54	printf("\thcidump <-i hciX> [-ah]\n");
55}
56
57void process_frames(int dev, int fd)
58{
59	char *data, *ctrl;
60	struct cmsghdr *cmsg;
61	struct msghdr msg;
62	struct iovec  iv;
63	int len, in;
64
65	if (snap_len < SNAP_LEN)
66		snap_len = SNAP_LEN;
67
68	if (!(data = malloc(snap_len))) {
69		perror("Can't allocate data buffer");
70		exit(1);
71	}
72
73	if (!(ctrl = malloc(100))) {
74		perror("Can't allocate control buffer");
75		exit(1);
76	}
77
78	printf("device: hci%d snap_len: %d filter: none\n", dev, snap_len);
79
80	while (1) {
81		iv.iov_base = data;
82		iv.iov_len  = snap_len;
83
84		msg.msg_iov = &iv;
85		msg.msg_iovlen = 1;
86		msg.msg_control = ctrl;
87		msg.msg_controllen = 100;
88
89		if( (len = recvmsg(fd, &msg, 0)) < 0 ){
90			perror("Receive failed");
91			exit(1);
92		}
93
94		/* Process control message */
95		in = 0;
96		cmsg = CMSG_FIRSTHDR(&msg);
97		while( cmsg ){
98			switch(cmsg->cmsg_type){
99				case HCI_CMSG_DIR:
100					in = *((int *)CMSG_DATA(cmsg));
101					break;
102			}
103			cmsg = CMSG_NXTHDR(&msg, cmsg);
104		}
105
106		/* Print data direction */
107		printf("%c ", (in ? '>' : '<'));
108
109		parse(data, len);
110
111		fflush(stdout);
112	}
113}
114
115int main(int argc, char *argv[])
116{
117	extern int optind, opterr, optopt;
118	extern char *optarg;
119	struct sockaddr_hci addr;
120	struct hci_filter flt;
121	int s, opt, dev;
122	long flags;
123
124	dev = 0;
125	flags = 0;
126
127	while ((opt=getopt(argc, argv,"i:s:ha")) != EOF) {
128		switch(opt) {
129		case 'i':
130			dev = atoi(optarg+3);
131			break;
132
133		case 'h':
134			flags |= DUMP_HEX;
135			break;
136
137		case 'a':
138			flags |= DUMP_ASCII;
139			break;
140
141		case 's':
142			snap_len = atoi(optarg);
143			break;
144
145		default:
146			usage();
147			exit(1);
148		}
149	}
150
151	/* Create HCI socket */
152	if( (s=socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0 ) {
153		perror("Can't create HCI socket");
154		exit(1);
155	}
156
157	opt = 1;
158	if( setsockopt(s, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0 ) {
159		perror("Can't enable data direction info");
160		exit(1);
161	}
162
163	/* Setup filter */
164	flt.type_mask  = ~0;      // All packet types
165	flt.event_mask[0] = ~0L;  // All events
166	flt.event_mask[1] = ~0L;
167	if (setsockopt(s, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
168		perror("Can't set HCI filter");
169		exit(1);
170	}
171
172	/* Bind socket to the HCI device */
173	addr.hci_family = AF_BLUETOOTH;
174	addr.hci_dev = dev;
175	if( bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ) {
176		printf("Can't attach to device hci%d. %s(%d)\n",
177					dev, strerror(errno), errno);
178		exit(1);
179	}
180
181	printf("HCIDump - HCI packet analyzer ver %s.\n", VERSION);
182
183	init_parser(flags);
184	process_frames(dev, s);
185
186	close(s);
187	return 0;
188}
189