3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2002-2003 Takashi Sasai <sasai@sm.sony.co.jp>
6 * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
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.
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.
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
35 #include <net/ethernet.h>
40 #define BNEP_GENERAL_ETHERNET 0x00
41 #define BNEP_CONTROL 0x01
42 #define BNEP_COMPRESSED_ETHERNET 0x02
43 #define BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY 0x03
44 #define BNEP_COMPRESSED_ETHERNET_DEST_ONLY 0x04
46 /* BNEP Control Packet Type */
47 #define BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD 0x00
48 #define BNEP_SETUP_CONNECTION_REQUEST_MSG 0x01
49 #define BNEP_SETUP_CONNECTION_RESPONSE_MSG 0x02
50 #define BNEP_FILTER_NET_TYPE_SET_MSG 0x03
51 #define BNEP_FILTER_NET_TYPE_RESPONSE_MSG 0x04
52 #define BNEP_FILTER_MULT_ADDR_SET_MSG 0x05
53 #define BNEP_FILTER_MULT_ADDR_RESPONSE_MSG 0x06
55 /* BNEP Extension Type */
56 #define BNEP_EXTENSION_CONTROL 0x00
58 #ifndef ETHERTYPE_IPV6
59 #define ETHERTYPE_IPV6 ETH_P_IPV6
62 static char *get_macaddr(struct frame *frm)
65 unsigned char *buf = frm->ptr;
67 sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
68 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
76 static void bnep_control(int level, struct frame *frm, int header_length)
82 uint8_t type = p_get_u8(frm);
84 p_indent(++level, frm);
86 case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
87 printf("Not Understood(0x%02x) type 0x%02x\n", type, p_get_u8(frm));
90 case BNEP_SETUP_CONNECTION_REQUEST_MSG:
91 uuid_size = p_get_u8(frm);
92 printf("Setup Req(0x%02x) size 0x%02x ", type, uuid_size);
95 uuid = p_get_u16(frm);
96 printf("dst 0x%x", uuid);
97 if ((s = get_uuid_name(uuid)) != 0)
99 uuid = p_get_u16(frm);
100 printf(" src 0x%x", uuid);
101 if ((s = get_uuid_name(uuid)) != 0)
106 uuid = p_get_u32(frm);
107 printf("dst 0x%x", uuid);
108 if ((s = get_uuid_name(uuid)) != 0)
110 uuid = p_get_u32(frm);
111 printf(" src 0x%x", uuid);
112 if ((s = get_uuid_name(uuid)) != 0)
117 uuid = p_get_u32(frm);
118 printf("dst 0x%x", uuid);
119 if ((s = get_uuid_name(uuid)) != 0)
123 uuid = p_get_u32(frm);
124 printf(" src 0x%x", uuid);
125 if ((s = get_uuid_name(uuid)) != 0)
132 frm->ptr += (uuid_size * 2);
133 frm->len -= (uuid_size * 2);
138 case BNEP_SETUP_CONNECTION_RESPONSE_MSG:
139 printf("Setup Rsp(0x%02x) res 0x%04x\n",
140 type, p_get_u16(frm));
143 case BNEP_FILTER_NET_TYPE_SET_MSG:
144 length = p_get_u16(frm);
145 printf("Filter NetType Set(0x%02x) len 0x%04x\n",
147 for (i = 0; i < length / 4; i++) {
148 p_indent(level + 1, frm);
149 printf("0x%04x - ", p_get_u16(frm));
150 printf("0x%04x\n", p_get_u16(frm));
154 case BNEP_FILTER_NET_TYPE_RESPONSE_MSG:
155 printf("Filter NetType Rsp(0x%02x) res 0x%04x\n",
156 type, p_get_u16(frm));
159 case BNEP_FILTER_MULT_ADDR_SET_MSG:
160 length = p_get_u16(frm);
161 printf("Filter MultAddr Set(0x%02x) len 0x%04x\n",
163 for (i = 0; i < length / 12; i++) {
164 p_indent(level + 1, frm);
165 printf("%s - ", get_macaddr(frm));
166 printf("%s\n", get_macaddr(frm));
170 case BNEP_FILTER_MULT_ADDR_RESPONSE_MSG:
171 printf("Filter MultAddr Rsp(0x%02x) res 0x%04x\n",
172 type, p_get_u16(frm));
176 printf("Unknown control type(0x%02x)\n", type);
177 raw_ndump(level + 1, frm, header_length - 1);
178 frm->ptr += header_length - 1;
179 frm->len -= header_length - 1;
184 static void bnep_eval_extension(int level, struct frame *frm)
186 uint8_t type = p_get_u8(frm);
187 uint8_t length = p_get_u8(frm);
188 int extension = type & 0x80;
190 p_indent(level, frm);
192 switch (type & 0x7f) {
193 case BNEP_EXTENSION_CONTROL:
194 printf("Ext Control(0x%02x|%s) len 0x%02x\n",
195 type & 0x7f, extension ? "1" : "0", length);
196 bnep_control(level, frm, length);
200 printf("Ext Unknown(0x%02x|%s) len 0x%02x\n",
201 type & 0x7f, extension ? "1" : "0", length);
202 raw_ndump(level + 1, frm, length);
208 bnep_eval_extension(level, frm);
211 void bnep_dump(int level, struct frame *frm)
213 uint8_t type = p_get_u8(frm);
214 uint16_t proto = 0x0000;
215 int extension = type & 0x80;
217 p_indent(level, frm);
219 switch (type & 0x7f) {
221 printf("BNEP: Control(0x%02x|%s)\n",
222 type & 0x7f, extension ? "1" : "0");
223 bnep_control(level, frm, -1);
226 case BNEP_COMPRESSED_ETHERNET:
227 printf("BNEP: Compressed(0x%02x|%s)\n",
228 type & 0x7f, extension ? "1" : "0");
229 p_indent(++level, frm);
230 proto = p_get_u16(frm);
231 printf("[proto 0x%04x]\n", proto);
234 case BNEP_GENERAL_ETHERNET:
235 printf("BNEP: General ethernet(0x%02x|%s)\n",
236 type & 0x7f, extension ? "1" : "0");
237 p_indent(++level, frm);
238 printf("dst %s ", get_macaddr(frm));
239 printf("src %s ", get_macaddr(frm));
240 proto = p_get_u16(frm);
241 printf("[proto 0x%04x]\n", proto);
244 case BNEP_COMPRESSED_ETHERNET_DEST_ONLY:
245 printf("BNEP: Compressed DestOnly(0x%02x|%s)\n",
246 type & 0x7f, extension ? "1" : "0");
247 p_indent(++level, frm);
248 printf("dst %s ", get_macaddr(frm));
249 proto = p_get_u16(frm);
250 printf("[proto 0x%04x]\n", proto);
253 case BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY:
254 printf("BNEP: Compressed SrcOnly(0x%02x|%s)\n",
255 type & 0x7f, extension ? "1" : "0");
256 p_indent(++level, frm);
257 printf("src %s ", get_macaddr(frm));
258 proto = p_get_u16(frm);
259 printf("[proto 0x%04x]\n", proto);
263 printf("(Unknown packet type)\n");
269 bnep_eval_extension(++level, frm);
271 /* Control packet => No payload info */
272 if ((type & 0x7f) == BNEP_CONTROL)
276 if (proto == 0x8100) {
277 p_indent(level, frm);
278 printf("802.1p Header: 0x%04x ", p_get_u16(frm));
279 proto = p_get_u16(frm);
280 printf("[proto 0x%04x]\n", proto);
283 if (!(parser.flags & DUMP_VERBOSE)) {
284 raw_dump(level, frm);
290 p_indent(++level, frm);
292 arp_dump(level, frm);
295 case ETHERTYPE_REVARP:
296 p_indent(++level, frm);
298 arp_dump(level, frm);
302 p_indent(++level, frm);
308 p_indent(++level, frm);
314 raw_dump(level, frm);