2 * packet-ieee80211-netmon.c
3 * Decode packets with a Network Monitor 802.11 radio header
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <epan/packet.h>
33 static int proto_netmon_802_11
= -1;
35 #define MIN_HEADER_LEN 32
38 #define OP_MODE_STA 0x00000001 /* station mode */
39 #define OP_MODE_AP 0x00000002 /* AP mode */
40 #define OP_MODE_STA_EXT 0x00000004 /* extensible station mode */
41 #define OP_MODE_MON 0x80000000 /* monitor mode */
44 #define PHY_TYPE_11A 4
45 #define PHY_TYPE_11B 5
46 #define PHY_TYPE_11G 6
47 #define PHY_TYPE_11N 7
49 static int hf_netmon_802_11_version
= -1;
50 static int hf_netmon_802_11_length
= -1;
51 static int hf_netmon_802_11_op_mode
= -1;
52 static int hf_netmon_802_11_op_mode_sta
= -1;
53 static int hf_netmon_802_11_op_mode_ap
= -1;
54 static int hf_netmon_802_11_op_mode_sta_ext
= -1;
55 static int hf_netmon_802_11_op_mode_mon
= -1;
56 /* static int hf_netmon_802_11_flags = -1; */
57 static int hf_netmon_802_11_phy_type
= -1;
58 static int hf_netmon_802_11_channel
= -1;
59 static int hf_netmon_802_11_frequency
= -1;
60 static int hf_netmon_802_11_rssi
= -1;
61 static int hf_netmon_802_11_datarate
= -1;
62 static int hf_netmon_802_11_timestamp
= -1;
64 static gint ett_netmon_802_11
= -1;
65 static gint ett_netmon_802_11_op_mode
= -1;
67 static dissector_handle_t ieee80211_handle
;
70 dissect_netmon_802_11(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
72 proto_tree
*wlan_tree
, *opmode_tree
;
83 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "WLAN");
84 col_clear(pinfo
->cinfo
, COL_INFO
);
87 version
= tvb_get_guint8(tvb
, offset
);
88 length
= tvb_get_letohs(tvb
, offset
+1);
89 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "NetMon WLAN Capture v%u, Length %u",
95 if (length
< MIN_HEADER_LEN
) {
100 /* Dissect the packet */
102 ti
= proto_tree_add_item(tree
, proto_netmon_802_11
, tvb
, 0, length
,
104 wlan_tree
= proto_item_add_subtree(ti
, ett_netmon_802_11
);
105 proto_tree_add_item(wlan_tree
, hf_netmon_802_11_version
, tvb
, offset
, 1,
108 proto_tree_add_item(wlan_tree
, hf_netmon_802_11_length
, tvb
, offset
, 2,
111 ti
= proto_tree_add_item(wlan_tree
, hf_netmon_802_11_op_mode
, tvb
, offset
,
112 4, ENC_LITTLE_ENDIAN
);
113 opmode_tree
= proto_item_add_subtree(ti
, ett_netmon_802_11_op_mode
);
114 proto_tree_add_item(opmode_tree
, hf_netmon_802_11_op_mode_sta
, tvb
, offset
,
115 4, ENC_LITTLE_ENDIAN
);
116 proto_tree_add_item(opmode_tree
, hf_netmon_802_11_op_mode_ap
, tvb
, offset
,
117 4, ENC_LITTLE_ENDIAN
);
118 proto_tree_add_item(opmode_tree
, hf_netmon_802_11_op_mode_sta_ext
, tvb
,
119 offset
, 4, ENC_LITTLE_ENDIAN
);
120 proto_tree_add_item(opmode_tree
, hf_netmon_802_11_op_mode_mon
, tvb
, offset
,
121 4, ENC_LITTLE_ENDIAN
);
123 flags
= tvb_get_letohl(tvb
, offset
);
125 if (flags
!= 0xffffffff) {
126 proto_tree_add_item(wlan_tree
, hf_netmon_802_11_phy_type
, tvb
, offset
, 4,
129 channel
= tvb_get_letohl(tvb
, offset
);
130 if (channel
< 1000) {
131 proto_tree_add_uint(wlan_tree
, hf_netmon_802_11_channel
,
132 tvb
, offset
, 4, channel
);
134 proto_tree_add_uint_format_value(wlan_tree
, hf_netmon_802_11_frequency
,
135 tvb
, offset
, 4, channel
,
139 rssi
= tvb_get_letohl(tvb
, offset
);
140 proto_tree_add_int_format_value(wlan_tree
, hf_netmon_802_11_rssi
,
141 tvb
, offset
, 4, rssi
,
144 rate
= tvb_get_guint8(tvb
, offset
);
146 proto_tree_add_uint_format_value(wlan_tree
, hf_netmon_802_11_datarate
,
147 tvb
, offset
, 1, rate
,
150 proto_tree_add_uint_format_value(wlan_tree
, hf_netmon_802_11_datarate
,
151 tvb
, offset
, 1, rate
,
157 proto_tree_add_item(wlan_tree
, hf_netmon_802_11_timestamp
, tvb
, offset
, 8,
168 /* dissect the 802.11 header next */
169 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
170 call_dissector(ieee80211_handle
, next_tvb
, pinfo
, tree
);
175 proto_register_netmon_802_11(void)
177 static const value_string phy_type
[] = {
178 { PHY_TYPE_11A
, "802.11a" },
179 { PHY_TYPE_11B
, "802.11b" },
180 { PHY_TYPE_11G
, "802.11g" },
181 { PHY_TYPE_11N
, "802.11n" },
185 static hf_register_info hf
[] = {
186 { &hf_netmon_802_11_version
, { "Header revision", "netmon_802_11.version", FT_UINT8
,
187 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
188 { &hf_netmon_802_11_length
, { "Header length", "netmon_802_11.length", FT_UINT16
,
189 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
190 { &hf_netmon_802_11_op_mode
, { "Operation mode", "netmon_802_11.op_mode", FT_UINT32
,
191 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
192 { &hf_netmon_802_11_op_mode_sta
, { "Station mode", "netmon_802_11.op_mode.sta", FT_UINT32
,
193 BASE_HEX
, NULL
, OP_MODE_STA
, NULL
, HFILL
} },
194 { &hf_netmon_802_11_op_mode_ap
, { "AP mode", "netmon_802_11.op_mode.ap", FT_UINT32
,
195 BASE_HEX
, NULL
, OP_MODE_AP
, NULL
, HFILL
} },
196 { &hf_netmon_802_11_op_mode_sta_ext
, { "Extensible station mode", "netmon_802_11.op_mode.sta_ext", FT_UINT32
,
197 BASE_HEX
, NULL
, OP_MODE_STA_EXT
, NULL
, HFILL
} },
198 { &hf_netmon_802_11_op_mode_mon
, { "Monitor mode", "netmon_802_11.op_mode.on", FT_UINT32
,
199 BASE_HEX
, NULL
, OP_MODE_MON
, NULL
, HFILL
} },
201 { &hf_netmon_802_11_flags
, { "Flags", "netmon_802_11.flags", FT_UINT32
,
202 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
204 { &hf_netmon_802_11_phy_type
, { "PHY type", "netmon_802_11.phy_type", FT_UINT32
,
205 BASE_DEC
, VALS(phy_type
), 0x0, NULL
, HFILL
} },
206 { &hf_netmon_802_11_channel
, { "Channel", "netmon_802_11.channel", FT_UINT32
,
207 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
208 { &hf_netmon_802_11_frequency
, { "Center frequency", "netmon_802_11.frequency", FT_UINT32
,
209 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
210 { &hf_netmon_802_11_rssi
, { "RSSI", "netmon_802_11.rssi", FT_INT32
,
211 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
212 { &hf_netmon_802_11_datarate
, { "Data rate", "netmon_802_11.datarate", FT_UINT32
,
213 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
215 * XXX - is this host, or MAC, time stamp?
216 * It might be a FILETIME.
218 { &hf_netmon_802_11_timestamp
, { "Timestamp", "netmon_802_11.timestamp", FT_UINT64
,
219 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
221 static gint
*ett
[] = {
223 &ett_netmon_802_11_op_mode
226 proto_netmon_802_11
= proto_register_protocol("NetMon 802.11 capture header",
229 proto_register_field_array(proto_netmon_802_11
, hf
, array_length(hf
));
230 proto_register_subtree_array(ett
, array_length(ett
));
234 proto_reg_handoff_netmon_802_11(void)
236 dissector_handle_t netmon_802_11_handle
;
238 /* handle for 802.11 dissector */
239 ieee80211_handle
= find_dissector("wlan");
240 netmon_802_11_handle
= new_create_dissector_handle(dissect_netmon_802_11
,
241 proto_netmon_802_11
);
242 dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_NETMON
, netmon_802_11_handle
);