3 * Decode packets with a Prism header
5 * Prism II-based wlan devices have a monitoring mode that sticks
6 * a proprietary header on each packet with lots of good
7 * information. This file is responsible for decoding that
12 * $Id: packet-prism.c,v 1.10 2003/03/08 11:43:54 jmayer Exp $
14 * Ethereal - Network traffic analyzer
15 * By Gerald Combs <gerald@ethereal.com>
16 * Copyright 1998 Gerald Combs
18 * Copied from README.developer
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 #include <epan/packet.h>
42 #include "packet-ieee80211.h"
43 #include "packet-prism.h"
44 #include "packet-wlancap.h"
47 static int proto_prism = -1;
50 static int hf_prism_msgcode = -1;
51 static int hf_prism_msglen = -1;
56 unsigned short status, len;
60 /* header attached during prism monitor mode */
62 unsigned int msgcode, msglen;
64 struct val_80211 hosttime, mactime, channel, rssi, sq, signal,
65 noise, rate, istx, frmlen;
68 #define VALFIELDS(name) \
69 static int hf_prism_ ## name ## _data = -1
81 static gint ett_prism = -1;
83 static dissector_handle_t ieee80211_handle;
84 static dissector_handle_t wlancap_handle;
87 capture_prism(const guchar *pd, int offset, int len, packet_counts *ld)
91 if (!BYTES_ARE_IN_FRAME(offset, len, sizeof(guint32) *2 )) {
97 length = pntohl(pd+sizeof(guint32));
99 /* Handle the new type of capture format */
100 if (cookie == WLANCAP_MAGIC_COOKIE_V1) {
101 if(!BYTES_ARE_IN_FRAME(offset, len, length)) {
107 /* We have an old capture format */
108 if(!BYTES_ARE_IN_FRAME(offset, len, (int)sizeof(struct prism_hdr))) {
112 offset += sizeof(struct prism_hdr);
115 /* 802.11 header follows */
116 capture_ieee80211(pd, offset, len, ld);
121 * yah, I know, macros, ugh, but it makes the code
122 * below more readable
124 #define IFHELP(size, name, var, str) \
125 proto_tree_add_uint_format(prism_tree, hf_prism_ ## name, \
126 tvb, offset, size, hdr.var, str, hdr.var); \
128 #define INTFIELD(size, name, str) IFHELP(size, name, name, str)
129 #define VALFIELD(name, str) \
130 proto_tree_add_uint_format(prism_tree, hf_prism_ ## name ## _data, \
131 tvb, offset, 12, hdr.name.data, \
132 str ": 0x%x (DID 0x%x, Status 0x%x, Length 0x%x)", \
133 hdr.name.data, hdr.name.did, \
134 hdr.name.status, hdr.name.len); \
138 dissect_prism(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
140 struct prism_hdr hdr;
141 proto_tree *prism_tree;
149 /* handle the new capture type. */
150 msgcode = tvb_get_ntohl(tvb, offset);
151 if (msgcode == WLANCAP_MAGIC_COOKIE_V1) {
152 call_dissector(wlancap_handle, tvb, pinfo, tree);
156 tvb_memcpy(tvb, (guint8 *)&hdr, offset, sizeof(hdr));
158 if(check_col(pinfo->cinfo, COL_PROTOCOL))
159 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Prism");
160 if(check_col(pinfo->cinfo, COL_INFO))
161 col_clear(pinfo->cinfo, COL_INFO);
163 if(check_col(pinfo->cinfo, COL_INFO))
164 col_add_fstr(pinfo->cinfo, COL_INFO, "Device: %.16s "
165 "Message 0x%x, Length %d", hdr.devname,
166 hdr.msgcode, hdr.msglen);
169 ti = proto_tree_add_protocol_format(tree, proto_prism,
170 tvb, 0, sizeof hdr, "Prism Monitoring Header");
171 prism_tree = proto_item_add_subtree(ti, ett_prism);
173 INTFIELD(4, msgcode, "Message Code: %d");
174 INTFIELD(4, msglen, "Message Length: %d");
175 proto_tree_add_text(prism_tree, tvb, offset, sizeof hdr.devname,
176 "Device: %s", hdr.devname);
177 offset += sizeof hdr.devname;
179 VALFIELD(hosttime, "Host Time");
180 VALFIELD(mactime, "MAC Time");
181 VALFIELD(channel, "Channel Time");
182 VALFIELD(rssi, "RSSI");
184 VALFIELD(signal, "Signal");
185 VALFIELD(noise, "Noise");
186 VALFIELD(rate, "Rate");
187 VALFIELD(istx, "IsTX");
188 VALFIELD(frmlen, "Frame Length");
191 /* dissect the 802.11 header next */
192 next_tvb = tvb_new_subset(tvb, sizeof hdr, -1, -1);
193 call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
196 #define IFHELP2(size, name, var, str) \
197 { &hf_prism_ ## name, { \
198 str, "prism." #var, size, BASE_HEX, NULL, 0x0, "", HFILL } },
199 #define INTFIELD2(size, name, str) IFHELP2(size, name, name, str)
200 #define VALFIELD2(name, str) \
201 IFHELP2(FT_UINT32, name ## _data, name.data, str " Field")
204 proto_register_prism(void)
206 static hf_register_info hf[] = {
207 INTFIELD2(FT_UINT32, msgcode, "Message Code")
208 INTFIELD2(FT_UINT32, msglen, "Message Length")
209 VALFIELD2(hosttime, "Host Time")
210 VALFIELD2(mactime, "MAC Time")
211 VALFIELD2(channel, "Channel Time")
212 VALFIELD2(rssi, "RSSI")
214 VALFIELD2(signal, "Signal")
215 VALFIELD2(noise, "Noise")
216 VALFIELD2(rate, "Rate")
217 VALFIELD2(istx, "IsTX")
218 VALFIELD2(frmlen, "Frame Length")
221 static gint *ett[] = {
225 proto_prism = proto_register_protocol("Prism", "Prism", "prism");
226 proto_register_field_array(proto_prism, hf, array_length(hf));
227 proto_register_subtree_array(ett, array_length(ett));
231 proto_reg_handoff_prism(void)
233 dissector_handle_t prism_handle;
235 /* handle for 802.11 dissector */
236 ieee80211_handle = find_dissector("wlan");
237 wlancap_handle = find_dissector("wlancap");
239 prism_handle = create_dissector_handle(dissect_prism, proto_prism);
240 dissector_add("wtap_encap", WTAP_ENCAP_PRISM_HEADER, prism_handle);