parser.h revision 692d324e39048b2397a2097f81493dd27f0293a4
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
26struct frame {
27	void	*data;
28	int	data_len;
29	void	*ptr;
30	int	len;
31	int	in;
32	int	handle;
33	int	cid;
34	long	flags;
35	struct	timeval ts;
36};
37
38/* Parser flags */
39#define DUMP_WIDTH	20
40
41#define DUMP_HEX	0x01
42#define DUMP_ASCII	0x02
43#define DUMP_TYPE_MASK	(DUMP_HEX | DUMP_ASCII)
44#define DUMP_TSTAMP	0x04
45#define DUMP_RAW	0x08
46
47/* Parser filter */
48#define FILT_HCI	0x0001
49#define FILT_SCO	0x0002
50#define FILT_L2CAP	0x0004
51#define FILT_RFCOMM	0x0008
52#define FILT_SDP	0x0010
53#define FILT_BNEP	0x0020
54#define FILT_CMTP	0x0040
55#define FILT_HIDP	0x0080
56
57#define STRUCT_OFFSET(type, member)  ((uint8_t *)&(((type *)NULL)->member) - \
58                                     (uint8_t *)((type *)NULL))
59
60#define STRUCT_END(type, member)     (STRUCT_OFFSET(type, member) + \
61                                     sizeof(((type *)NULL)->member))
62
63struct parser_t {
64	unsigned long flags;
65	unsigned long filter;
66	unsigned int defpsm;
67	int state;
68};
69
70extern struct parser_t parser;
71
72void init_parser(unsigned long flags, unsigned long filter,
73	unsigned int assume_psm);
74
75static inline int p_filter(unsigned long f)
76{
77	return !(parser.filter & f);
78}
79
80static inline void p_indent(int level, struct frame *f)
81{
82	if (level < 0) {
83		parser.state = 0;
84		return;
85	}
86
87	if (!parser.state) {
88		if (parser.flags & DUMP_TSTAMP)
89			printf("%8lu.%06lu ", f->ts.tv_sec, f->ts.tv_usec);
90		printf("%c ", (f->in ? '>' : '<'));
91		parser.state = 1;
92	} else
93		printf("  ");
94
95	if (level)
96		printf("%*c", (level*2), ' ');
97}
98
99/* get_uXX functions do byte swaping */
100
101/* use memmove to prevent gcc from using builtin memcpy */
102#define get_unaligned(p) \
103	({ __typeof__(*(p)) t; memmove(&t, (p), sizeof(t)); t; })
104
105static inline uint8_t get_u8(struct frame *frm)
106{
107	uint8_t *u8_ptr = frm->ptr;
108	frm->ptr += 1;
109	frm->len -= 1;
110	return *u8_ptr;
111}
112
113static inline uint16_t get_u16(struct frame *frm)
114{
115	uint16_t *u16_ptr = frm->ptr;
116	frm->ptr += 2;
117	frm->len -= 2;
118	return ntohs(get_unaligned(u16_ptr));
119}
120
121static inline uint32_t get_u32(struct frame *frm)
122{
123	uint32_t *u32_ptr = frm->ptr;
124	frm->ptr += 4;
125	frm->len -= 4;
126	return ntohl(get_unaligned(u32_ptr));
127}
128
129static inline uint64_t get_u64(struct frame *frm)
130{
131	uint64_t *u64_ptr = frm->ptr;
132	uint64_t u64 = get_unaligned(u64_ptr), tmp;
133	frm->ptr += 8;
134	frm->len -= 8;
135	tmp = ntohl(u64 & 0xffffffff);
136	u64 = (tmp << 32) | ntohl(u64 >> 32);
137	return u64;
138}
139
140static inline void get_u128(struct frame *frm, uint64_t *l, uint64_t *h)
141{
142	*h = get_u64(frm);
143	*l = get_u64(frm);
144}
145
146char *get_uuid_name(int uuid);
147
148void set_proto(uint16_t handle, uint16_t psm, uint32_t proto);
149uint32_t get_proto(uint16_t handle, uint16_t psm);
150
151void raw_dump(int level, struct frame *frm);
152void raw_ndump(int level, struct frame *frm, int num);
153void hci_dump(int level, struct frame *frm);
154void l2cap_dump(int level, struct frame *frm);
155void rfcomm_dump(int level, struct frame *frm);
156void sdp_dump(int level, struct frame *frm);
157void bnep_dump(int level, struct frame *frm);
158void cmtp_dump(int level, struct frame *frm);
159void hidp_dump(int level, struct frame *frm);
160
161static inline void parse(struct frame *frm)
162{
163	p_indent(-1, NULL);
164	if (parser.flags & DUMP_RAW)
165		raw_dump(0, frm);
166	else
167		hci_dump(0, frm);
168	fflush(stdout);
169}
170