• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2002-2003  Takashi Sasai <sasai@sm.sony.co.jp>
6  *  Copyright (C) 2003-2011  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 <unistd.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/types.h>
35 
36 #include <net/ethertypes.h>
37 
38 #include "parser.h"
39 
40 /* BNEP Type */
41 #define BNEP_GENERAL_ETHERNET			0x00
42 #define BNEP_CONTROL				0x01
43 #define BNEP_COMPRESSED_ETHERNET		0x02
44 #define BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY	0x03
45 #define BNEP_COMPRESSED_ETHERNET_DEST_ONLY	0x04
46 
47 /* BNEP Control Packet Type */
48 #define BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD	0x00
49 #define BNEP_SETUP_CONNECTION_REQUEST_MSG	0x01
50 #define BNEP_SETUP_CONNECTION_RESPONSE_MSG	0x02
51 #define BNEP_FILTER_NET_TYPE_SET_MSG		0x03
52 #define BNEP_FILTER_NET_TYPE_RESPONSE_MSG	0x04
53 #define BNEP_FILTER_MULT_ADDR_SET_MSG		0x05
54 #define BNEP_FILTER_MULT_ADDR_RESPONSE_MSG	0x06
55 
56 /* BNEP Extension Type */
57 #define BNEP_EXTENSION_CONTROL			0x00
58 
59 #ifndef ETHERTYPE_IPV6
60 #define ETHERTYPE_IPV6 ETH_P_IPV6
61 #endif
62 
get_macaddr(struct frame * frm)63 static char *get_macaddr(struct frame *frm)
64 {
65 	static char str[20];
66 	unsigned char *buf = frm->ptr;
67 
68 	sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
69 		buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
70 
71 	frm->ptr += 6;
72 	frm->len -= 6;
73 
74 	return str;
75 }
76 
bnep_control(int level,struct frame * frm,int header_length)77 static void bnep_control(int level, struct frame *frm, int header_length)
78 {
79 	uint8_t uuid_size;
80 	int i, length;
81 	char *s;
82 	uint32_t uuid = 0;
83 	uint8_t type = get_u8(frm);
84 
85 	p_indent(++level, frm);
86 	switch (type) {
87 	case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
88 		printf("Not Understood(0x%02x) type 0x%02x\n", type, get_u8(frm));
89 		break;
90 
91 	case BNEP_SETUP_CONNECTION_REQUEST_MSG:
92 		uuid_size = get_u8(frm);
93 		printf("Setup Req(0x%02x) size 0x%02x ", type, uuid_size);
94 		switch (uuid_size) {
95 		case 2:
96 			uuid = get_u16(frm);
97 			printf("dst 0x%x", uuid);
98 			if ((s = get_uuid_name(uuid)) != 0)
99 				printf("(%s)", s);
100 			uuid = get_u16(frm);
101 			printf(" src 0x%x", uuid);
102 			if ((s = get_uuid_name(uuid)) != 0)
103 				printf("(%s)", s);
104 			printf("\n");
105 			break;
106 		case 4:
107 			uuid = get_u32(frm);
108 			printf("dst 0x%x", uuid);
109 			if ((s = get_uuid_name(uuid)) != 0)
110 				printf("(%s)", s);
111 			uuid = get_u32(frm);
112 			printf(" src 0x%x", uuid);
113 			if ((s = get_uuid_name(uuid)) != 0)
114 				printf("(%s)", s);
115 			printf("\n");
116 			break;
117 		case 16:
118 			uuid = get_u32(frm);
119 			printf("dst 0x%x", uuid);
120 			if ((s = get_uuid_name(uuid)) != 0)
121 				printf("(%s)", s);
122 			frm->ptr += 12;
123 			frm->len -= 12;
124 			uuid = get_u32(frm);
125 			printf(" src 0x%x", uuid);
126 			if ((s = get_uuid_name(uuid)) != 0)
127 				printf("(%s)", s);
128 			printf("\n");
129 			frm->ptr += 12;
130 			frm->len -= 12;
131 			break;
132 		default:
133 			frm->ptr += (uuid_size * 2);
134 			frm->len -= (uuid_size * 2);
135 			break;
136 		}
137 		break;
138 
139 	case BNEP_SETUP_CONNECTION_RESPONSE_MSG:
140 		printf("Setup Rsp(0x%02x) res 0x%04x\n",
141 						type, get_u16(frm));
142 		break;
143 
144 	case BNEP_FILTER_NET_TYPE_SET_MSG:
145 		length = get_u16(frm);
146 		printf("Filter NetType Set(0x%02x) len 0x%04x\n",
147 							type, length);
148 		for (i = 0; i < length / 4; i++) {
149 			p_indent(level + 1, frm);
150 			printf("0x%04x - ", get_u16(frm));
151 			printf("0x%04x\n", get_u16(frm));
152 		}
153 		break;
154 
155 	case BNEP_FILTER_NET_TYPE_RESPONSE_MSG:
156 		printf("Filter NetType Rsp(0x%02x) res 0x%04x\n",
157 							type, get_u16(frm));
158 		break;
159 
160 	case BNEP_FILTER_MULT_ADDR_SET_MSG:
161 		length = get_u16(frm);
162 		printf("Filter MultAddr Set(0x%02x) len 0x%04x\n",
163 							type, length);
164 		for (i = 0; i < length / 12; i++) {
165 			p_indent(level + 1, frm);
166 			printf("%s - ", get_macaddr(frm));
167 			printf("%s\n", get_macaddr(frm));
168 		}
169 		break;
170 
171 	case BNEP_FILTER_MULT_ADDR_RESPONSE_MSG:
172 		printf("Filter MultAddr Rsp(0x%02x) res 0x%04x\n",
173 							type, get_u16(frm));
174 		break;
175 
176 	default:
177 		printf("Unknown control type(0x%02x)\n", type);
178 		raw_ndump(level + 1, frm, header_length - 1);
179 		frm->ptr += header_length - 1;
180 		frm->len -= header_length - 1;
181 		return;
182 	}
183 }
184 
bnep_eval_extension(int level,struct frame * frm)185 static void bnep_eval_extension(int level, struct frame *frm)
186 {
187 	uint8_t type = get_u8(frm);
188 	uint8_t length = get_u8(frm);
189 	int extension = type & 0x80;
190 
191 	p_indent(level, frm);
192 
193 	switch (type & 0x7f) {
194 	case BNEP_EXTENSION_CONTROL:
195 		printf("Ext Control(0x%02x|%s) len 0x%02x\n",
196 				type & 0x7f, extension ? "1" : "0", length);
197 		bnep_control(level, frm, length);
198 		break;
199 
200 	default:
201 		printf("Ext Unknown(0x%02x|%s) len 0x%02x\n",
202 				type & 0x7f, extension ? "1" : "0", length);
203 		raw_ndump(level + 1, frm, length);
204 		frm->ptr += length;
205 		frm->len -= length;
206 	}
207 
208 	if (extension)
209 		bnep_eval_extension(level, frm);
210 }
211 
bnep_dump(int level,struct frame * frm)212 void bnep_dump(int level, struct frame *frm)
213 {
214 	uint8_t type = get_u8(frm);
215 	uint16_t proto = 0x0000;
216 	int extension = type & 0x80;
217 
218 	p_indent(level, frm);
219 
220 	switch (type & 0x7f) {
221 	case BNEP_CONTROL:
222 		printf("BNEP: Control(0x%02x|%s)\n",
223 					type & 0x7f, extension ? "1" : "0");
224 		bnep_control(level, frm, -1);
225 		break;
226 
227 	case BNEP_COMPRESSED_ETHERNET:
228 		printf("BNEP: Compressed(0x%02x|%s)\n",
229 					type & 0x7f, extension ? "1" : "0");
230 		p_indent(++level, frm);
231 		proto = get_u16(frm);
232 		printf("[proto 0x%04x]\n", proto);
233 		break;
234 
235 	case BNEP_GENERAL_ETHERNET:
236 		printf("BNEP: General ethernet(0x%02x|%s)\n",
237 					type & 0x7f, extension ? "1" : "0");
238 		p_indent(++level, frm);
239 		printf("dst %s ", get_macaddr(frm));
240 		printf("src %s ", get_macaddr(frm));
241 		proto = get_u16(frm);
242 		printf("[proto 0x%04x]\n", proto);
243 		break;
244 
245 	case BNEP_COMPRESSED_ETHERNET_DEST_ONLY:
246 		printf("BNEP: Compressed DestOnly(0x%02x|%s)\n",
247 					type & 0x7f, extension ? "1" : "0");
248 		p_indent(++level, frm);
249 		printf("dst %s ", get_macaddr(frm));
250 		proto = get_u16(frm);
251 		printf("[proto 0x%04x]\n", proto);
252 		break;
253 
254 	case BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY:
255 		printf("BNEP: Compressed SrcOnly(0x%02x|%s)\n",
256 					type & 0x7f, extension ? "1" : "0");
257 		p_indent(++level, frm);
258 		printf("src %s ", get_macaddr(frm));
259 		proto = get_u16(frm);
260 		printf("[proto 0x%04x]\n", proto);
261 		break;
262 
263 	default:
264 		printf("(Unknown packet type)\n");
265 		return;
266 	}
267 
268 	/* Extension info */
269 	if (extension)
270 		bnep_eval_extension(++level, frm);
271 
272 	/* Control packet => No payload info */
273 	if ((type & 0x7f) == BNEP_CONTROL)
274 		return;
275 
276 	/* 802.1p header */
277 	if (proto == 0x8100) {
278 		p_indent(level, frm);
279 		printf("802.1p Header: 0x%04x ", get_u16(frm));
280 		proto = get_u16(frm);
281 		printf("[proto 0x%04x]\n", proto);
282 	}
283 
284 	if (!(parser.flags & DUMP_VERBOSE)) {
285 		raw_dump(level, frm);
286 		return;
287 	}
288 
289 	switch (proto) {
290 	case ETHERTYPE_ARP:
291 		p_indent(++level, frm);
292 		printf("ARP: ");
293 		arp_dump(level, frm);
294 		break;
295 
296 	case ETHERTYPE_REVARP:
297 		p_indent(++level, frm);
298 		printf("RARP: ");
299 		arp_dump(level, frm);
300 		break;
301 
302 	case ETHERTYPE_IP:
303 		p_indent(++level, frm);
304 		printf("IP: ");
305 		ip_dump(level, frm);
306 		break;
307 
308 	case ETHERTYPE_IPV6:
309 		p_indent(++level, frm);
310 		printf("IPV6: ");
311 		ip_dump(level, frm);
312 		break;
313 
314 	default:
315 		raw_dump(level, frm);
316 		break;
317 	}
318 }
319