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.6 2002/01/21 07:36:38 guy 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.
39 #ifdef HAVE_SYS_TYPES_H
40 # include <sys/types.h>
45 #include <epan/packet.h>
46 #include "packet-ieee80211.h"
47 #include "packet-prism.h"
50 static int proto_prism = -1;
53 static int hf_prism_msgcode = -1;
54 static int hf_prism_msglen = -1;
59 unsigned short status, len;
63 /* header attached during prism monitor mode */
65 unsigned int msgcode, msglen;
67 struct val_80211 hosttime, mactime, channel, rssi, sq, signal,
68 noise, rate, istx, frmlen;
71 #define VALFIELDS(name) \
72 static int hf_prism_ ## name ## _data = -1
84 static gint ett_prism = -1;
86 static dissector_handle_t ieee80211_handle;
89 capture_prism(const u_char *pd, int offset, int len, packet_counts *ld)
91 if(!BYTES_ARE_IN_FRAME(offset, len, (int)sizeof(struct prism_hdr))) {
95 offset += sizeof(struct prism_hdr);
97 /* 802.11 header follows */
98 capture_ieee80211(pd, offset, len, ld);
102 * yah, I know, macros, ugh, but it makes the code
103 * below more readable
105 #define IFHELP(size, name, var, str) \
106 proto_tree_add_uint_format(prism_tree, hf_prism_ ## name, \
107 tvb, offset, size, hdr. ## var, str, hdr. ## var); \
109 #define INTFIELD(size, name, str) IFHELP(size, name, name, str)
110 #define VALFIELD(name, str) \
111 proto_tree_add_uint_format(prism_tree, hf_prism_ ## name ## _data, \
112 tvb, offset, 12, hdr. ## name ## .data, \
113 str ": 0x%x (DID 0x%x, Status 0x%x, Length 0x%x)", \
114 hdr. ## name ## .data, hdr. ## name ## .did, \
115 hdr. ## name ## .status, hdr. ## name ## .len); \
119 dissect_prism(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
121 struct prism_hdr hdr;
122 proto_tree *prism_tree;
127 if(check_col(pinfo->cinfo, COL_PROTOCOL))
128 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Prism");
129 if(check_col(pinfo->cinfo, COL_INFO))
130 col_clear(pinfo->cinfo, COL_INFO);
133 tvb_memcpy(tvb, (guint8 *)&hdr, offset, sizeof hdr);
135 if(check_col(pinfo->cinfo, COL_INFO))
136 col_add_fstr(pinfo->cinfo, COL_INFO, "Device: %.16s "
137 "Message 0x%x, Length %d", hdr.devname,
138 hdr.msgcode, hdr.msglen);
141 ti = proto_tree_add_protocol_format(tree, proto_prism,
142 tvb, 0, sizeof hdr, "Prism Monitoring Header");
143 prism_tree = proto_item_add_subtree(ti, ett_prism);
145 INTFIELD(4, msgcode, "Message Code: %d");
146 INTFIELD(4, msglen, "Message Length: %d");
147 proto_tree_add_text(prism_tree, tvb, offset, sizeof hdr.devname,
148 "Device: %s", hdr.devname);
149 offset += sizeof hdr.devname;
151 VALFIELD(hosttime, "Host Time");
152 VALFIELD(mactime, "MAC Time");
153 VALFIELD(channel, "Channel Time");
154 VALFIELD(rssi, "RSSI");
156 VALFIELD(signal, "Signal");
157 VALFIELD(noise, "Noise");
158 VALFIELD(rate, "Rate");
159 VALFIELD(istx, "IsTX");
160 VALFIELD(frmlen, "Frame Length");
163 /* dissect the 802.11 header next */
164 next_tvb = tvb_new_subset(tvb, sizeof hdr, -1, -1);
165 call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
168 #define IFHELP2(size, name, var, str) \
169 { &hf_prism_ ## name, { \
170 str, "prism." #var, size, BASE_HEX, NULL, 0x0, "", HFILL } },
171 #define INTFIELD2(size, name, str) IFHELP2(size, name, name, str)
172 #define VALFIELD2(name, str) \
173 IFHELP2(FT_UINT32, name ## _data, name ## .data, str ## " Field")
176 proto_register_prism(void)
178 static hf_register_info hf[] = {
179 INTFIELD2(FT_UINT32, msgcode, "Message Code")
180 INTFIELD2(FT_UINT32, msglen, "Message Length")
181 VALFIELD2(hosttime, "Host Time")
182 VALFIELD2(mactime, "MAC Time")
183 VALFIELD2(channel, "Channel Time")
184 VALFIELD2(rssi, "RSSI")
186 VALFIELD2(signal, "Signal")
187 VALFIELD2(noise, "Noise")
188 VALFIELD2(rate, "Rate")
189 VALFIELD2(istx, "IsTX")
190 VALFIELD2(frmlen, "Frame Length")
193 static gint *ett[] = {
197 proto_prism = proto_register_protocol("Prism", "Prism", "prism");
198 proto_register_field_array(proto_prism, hf, array_length(hf));
199 proto_register_subtree_array(ett, array_length(ett));
203 proto_reg_handoff_prism(void)
205 dissector_handle_t prism_handle;
207 /* handle for 802.11 dissector */
208 ieee80211_handle = find_dissector("wlan");
210 prism_handle = create_dissector_handle(dissect_prism, proto_prism);
211 dissector_add("wtap_encap", WTAP_ENCAP_PRISM_HEADER, prism_handle);