blob: 3fc8baaa3bdc45a1a3c4ae73c13c600184179a4a [file] [log] [blame]
Wade Guthrie0d438532012-05-18 14:18:50 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// This code is derived from the 'iw' source code. The copyright and license
6// of that code is as follows:
7//
8// Copyright (c) 2007, 2008 Johannes Berg
9// Copyright (c) 2007 Andy Lutomirski
10// Copyright (c) 2007 Mike Kershaw
11// Copyright (c) 2008-2009 Luis R. Rodriguez
12//
13// Permission to use, copy, modify, and/or distribute this software for any
14// purpose with or without fee is hereby granted, provided that the above
15// copyright notice and this permission notice appear in all copies.
16//
17// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
repo syncdc085c82012-12-28 08:54:41 -080025#include "shill/nl80211_message.h"
Wade Guthrie0d438532012-05-18 14:18:50 -070026
Wade Guthriebdcdaa72013-03-04 12:47:12 -080027#include <limits.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070028#include <netlink/msg.h>
29#include <netlink/netlink.h>
30
Wade Guthrie89e6cb32013-03-07 08:03:45 -080031#include <map>
Wade Guthrie0d438532012-05-18 14:18:50 -070032#include <string>
Wade Guthrie89e6cb32013-03-07 08:03:45 -080033#include <vector>
Wade Guthrie0d438532012-05-18 14:18:50 -070034
Wade Guthrie68da97c2013-02-26 13:09:35 -080035#include <base/bind.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070036#include <base/stringprintf.h>
37
repo sync90ee0fa2012-12-18 10:08:08 -080038#include "shill/attribute_list.h"
Wade Guthrie0d438532012-05-18 14:18:50 -070039#include "shill/ieee80211.h"
40#include "shill/logging.h"
Wade Guthrief162f8b2013-02-27 14:13:55 -080041#include "shill/netlink_attribute.h"
Wade Guthrie89e6cb32013-03-07 08:03:45 -080042#include "shill/refptr_types.h"
Wade Guthrie0d438532012-05-18 14:18:50 -070043
Wade Guthrie68da97c2013-02-26 13:09:35 -080044using base::Bind;
Wade Guthrie0d438532012-05-18 14:18:50 -070045using base::LazyInstance;
46using base::StringAppendF;
Wade Guthrie0d438532012-05-18 14:18:50 -070047using std::map;
48using std::string;
49using std::vector;
50
51namespace shill {
52
53namespace {
repo syncdc085c82012-12-28 08:54:41 -080054LazyInstance<Nl80211MessageDataCollector> g_datacollector =
Wade Guthrie0d438532012-05-18 14:18:50 -070055 LAZY_INSTANCE_INITIALIZER;
56} // namespace
57
Wade Guthrie0d438532012-05-18 14:18:50 -070058const uint8_t Nl80211Frame::kMinimumFrameByteCount = 26;
59const uint8_t Nl80211Frame::kFrameTypeMask = 0xfc;
60
Wade Guthriebdcdaa72013-03-04 12:47:12 -080061const char Nl80211Message::kBogusMacAddress[] = "XX:XX:XX:XX:XX:XX";
repo syncdc085c82012-12-28 08:54:41 -080062const unsigned int Nl80211Message::kEthernetAddressBytes = 6;
Wade Guthriebee87c22013-03-06 11:00:46 -080063const char Nl80211Message::kMessageTypeString[] = "nl80211";
repo syncdc085c82012-12-28 08:54:41 -080064map<uint16_t, string> *Nl80211Message::reason_code_string_ = NULL;
65map<uint16_t, string> *Nl80211Message::status_code_string_ = NULL;
Wade Guthriebdcdaa72013-03-04 12:47:12 -080066uint16_t Nl80211Message::nl80211_message_type_ = kIllegalMessageType;
67
Wade Guthriebee87c22013-03-06 11:00:46 -080068// static
Paul Stewart2ddf2c62013-04-16 09:47:34 -070069uint16_t Nl80211Message::GetMessageType() {
70 return nl80211_message_type_;
71}
72
73// static
Wade Guthriebee87c22013-03-06 11:00:46 -080074void Nl80211Message::SetMessageType(uint16_t message_type) {
75 if (message_type == NetlinkMessage::kIllegalMessageType) {
76 LOG(FATAL) << "Absolutely need a legal message type for Nl80211 messages.";
77 }
78 nl80211_message_type_ = message_type;
79}
80
repo sync0efa9f02012-12-28 13:40:20 -080081bool Nl80211Message::InitFromNlmsg(const nlmsghdr *const_msg) {
82 if (!const_msg) {
83 LOG(ERROR) << "Null |msg| parameter";
Wade Guthrie0d438532012-05-18 14:18:50 -070084 return false;
85 }
Wade Guthriebdcdaa72013-03-04 12:47:12 -080086 ByteString message(reinterpret_cast<const unsigned char *>(const_msg),
87 const_msg->nlmsg_len);
Wade Guthrie0d438532012-05-18 14:18:50 -070088
Wade Guthriebdcdaa72013-03-04 12:47:12 -080089 if (!InitAndStripHeader(&message)) {
90 return false;
91 }
repo sync0efa9f02012-12-28 13:40:20 -080092
93 // Attributes.
94 // Parse the attributes from the nl message payload into the 'tb' array.
95 nlattr *tb[NL80211_ATTR_MAX + 1];
Wade Guthriebdcdaa72013-03-04 12:47:12 -080096 nla_parse(tb, NL80211_ATTR_MAX,
97 reinterpret_cast<nlattr *>(message.GetData()), message.GetLength(),
98 NULL);
repo sync0efa9f02012-12-28 13:40:20 -080099
Wade Guthrie0d438532012-05-18 14:18:50 -0700100 for (int i = 0; i < NL80211_ATTR_MAX + 1; ++i) {
101 if (tb[i]) {
repo sync0efa9f02012-12-28 13:40:20 -0800102 // TODO(wdg): When Nl80211Messages instantiate their own attributes,
103 // this call should, instead, call |SetAttributeFromNlAttr|.
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800104 attributes_->CreateAndInitAttribute(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800105 i, tb[i], Bind(&NetlinkAttribute::NewNl80211AttributeFromId));
Wade Guthrie0d438532012-05-18 14:18:50 -0700106 }
107 }
108
109 // Convert integer values provided by libnl (for example, from the
110 // NL80211_ATTR_STATUS_CODE or NL80211_ATTR_REASON_CODE attribute) into
111 // strings describing the status.
Wade Guthried4977f22012-08-22 12:37:54 -0700112 if (!reason_code_string_) {
113 reason_code_string_ = new map<uint16_t, string>;
114 (*reason_code_string_)[IEEE_80211::kReasonCodeUnspecified] =
115 "Unspecified reason";
116 (*reason_code_string_)[
117 IEEE_80211::kReasonCodePreviousAuthenticationInvalid] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700118 "Previous authentication no longer valid";
Wade Guthried4977f22012-08-22 12:37:54 -0700119 (*reason_code_string_)[IEEE_80211::kReasonCodeSenderHasLeft] =
120 "Deauthentcated because sending STA is leaving (or has left) IBSS or "
121 "ESS";
122 (*reason_code_string_)[IEEE_80211::kReasonCodeInactivity] =
123 "Disassociated due to inactivity";
124 (*reason_code_string_)[IEEE_80211::kReasonCodeTooManySTAs] =
125 "Disassociated because AP is unable to handle all currently associated "
126 "STAs";
127 (*reason_code_string_)[IEEE_80211::kReasonCodeNonAuthenticated] =
128 "Class 2 frame received from nonauthenticated STA";
129 (*reason_code_string_)[IEEE_80211::kReasonCodeNonAssociated] =
130 "Class 3 frame received from nonassociated STA";
131 (*reason_code_string_)[IEEE_80211::kReasonCodeDisassociatedHasLeft] =
132 "Disassociated because sending STA is leaving (or has left) BSS";
133 (*reason_code_string_)[
134 IEEE_80211::kReasonCodeReassociationNotAuthenticated] =
135 "STA requesting (re)association is not authenticated with responding "
136 "STA";
137 (*reason_code_string_)[IEEE_80211::kReasonCodeUnacceptablePowerCapability] =
138 "Disassociated because the information in the Power Capability "
139 "element is unacceptable";
140 (*reason_code_string_)[
141 IEEE_80211::kReasonCodeUnacceptableSupportedChannelInfo] =
142 "Disassociated because the information in the Supported Channels "
143 "element is unacceptable";
144 (*reason_code_string_)[IEEE_80211::kReasonCodeInvalidInfoElement] =
145 "Invalid information element, i.e., an information element defined in "
146 "this standard for which the content does not meet the specifications "
147 "in Clause 7";
148 (*reason_code_string_)[IEEE_80211::kReasonCodeMICFailure] =
149 "Message integrity code (MIC) failure";
150 (*reason_code_string_)[IEEE_80211::kReasonCode4WayTimeout] =
151 "4-Way Handshake timeout";
152 (*reason_code_string_)[IEEE_80211::kReasonCodeGroupKeyHandshakeTimeout] =
153 "Group Key Handshake timeout";
154 (*reason_code_string_)[IEEE_80211::kReasonCodeDifferenIE] =
155 "Information element in 4-Way Handshake different from "
156 "(Re)Association Request/Probe Response/Beacon frame";
157 (*reason_code_string_)[IEEE_80211::kReasonCodeGroupCipherInvalid] =
158 "Invalid group cipher";
159 (*reason_code_string_)[IEEE_80211::kReasonCodePairwiseCipherInvalid] =
160 "Invalid pairwise cipher";
161 (*reason_code_string_)[IEEE_80211::kReasonCodeAkmpInvalid] =
162 "Invalid AKMP";
163 (*reason_code_string_)[IEEE_80211::kReasonCodeUnsupportedRsnIeVersion] =
164 "Unsupported RSN information element version";
165 (*reason_code_string_)[IEEE_80211::kReasonCodeInvalidRsnIeCaps] =
166 "Invalid RSN information element capabilities";
167 (*reason_code_string_)[IEEE_80211::kReasonCode8021XAuth] =
168 "IEEE 802.1X authentication failed";
169 (*reason_code_string_)[IEEE_80211::kReasonCodeCipherSuiteRejected] =
170 "Cipher suite rejected because of the security policy";
171 (*reason_code_string_)[IEEE_80211::kReasonCodeUnspecifiedQoS] =
172 "Disassociated for unspecified, QoS-related reason";
173 (*reason_code_string_)[IEEE_80211::kReasonCodeQoSBandwidth] =
174 "Disassociated because QoS AP lacks sufficient bandwidth for this "
175 "QoS STA";
176 (*reason_code_string_)[IEEE_80211::kReasonCodeiPoorConditions] =
177 "Disassociated because excessive number of frames need to be "
178 "acknowledged, but are not acknowledged due to AP transmissions "
179 "and/or poor channel conditions";
180 (*reason_code_string_)[IEEE_80211::kReasonCodeOutsideTxop] =
181 "Disassociated because STA is transmitting outside the limits of its "
182 "TXOPs";
183 (*reason_code_string_)[IEEE_80211::kReasonCodeStaLeaving] =
184 "Requested from peer STA as the STA is leaving the BSS (or resetting)";
185 (*reason_code_string_)[IEEE_80211::kReasonCodeUnacceptableMechanism] =
186 "Requested from peer STA as it does not want to use the mechanism";
187 (*reason_code_string_)[IEEE_80211::kReasonCodeSetupRequired] =
188 "Requested from peer STA as the STA received frames using the "
189 "mechanism for which a setup is required";
190 (*reason_code_string_)[IEEE_80211::kReasonCodeTimeout] =
191 "Requested from peer STA due to timeout";
192 (*reason_code_string_)[IEEE_80211::kReasonCodeCipherSuiteNotSupported] =
193 "Peer STA does not support the requested cipher suite";
194 (*reason_code_string_)[IEEE_80211::kReasonCodeInvalid] = "<INVALID REASON>";
195 }
196
197 if (!status_code_string_) {
198 status_code_string_ = new map<uint16_t, string>;
199 (*status_code_string_)[IEEE_80211::kStatusCodeSuccessful] = "Successful";
200 (*status_code_string_)[IEEE_80211::kStatusCodeFailure] =
201 "Unspecified failure";
202 (*status_code_string_)[IEEE_80211::kStatusCodeAllCapabilitiesNotSupported] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700203 "Cannot support all requested capabilities in the capability "
204 "information field";
Wade Guthried4977f22012-08-22 12:37:54 -0700205 (*status_code_string_)[IEEE_80211::kStatusCodeCantConfirmAssociation] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700206 "Reassociation denied due to inability to confirm that association "
207 "exists";
Wade Guthried4977f22012-08-22 12:37:54 -0700208 (*status_code_string_)[IEEE_80211::kStatusCodeAssociationDenied] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700209 "Association denied due to reason outside the scope of this standard";
Wade Guthried4977f22012-08-22 12:37:54 -0700210 (*status_code_string_)[
211 IEEE_80211::kStatusCodeAuthenticationUnsupported] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700212 "Responding station does not support the specified authentication "
213 "algorithm";
Wade Guthried4977f22012-08-22 12:37:54 -0700214 (*status_code_string_)[IEEE_80211::kStatusCodeOutOfSequence] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700215 "Received an authentication frame with authentication transaction "
216 "sequence number out of expected sequence";
Wade Guthried4977f22012-08-22 12:37:54 -0700217 (*status_code_string_)[IEEE_80211::kStatusCodeChallengeFailure] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700218 "Authentication rejected because of challenge failure";
Wade Guthried4977f22012-08-22 12:37:54 -0700219 (*status_code_string_)[IEEE_80211::kStatusCodeFrameTimeout] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700220 "Authentication rejected due to timeout waiting for next frame in "
221 "sequence";
Wade Guthried4977f22012-08-22 12:37:54 -0700222 (*status_code_string_)[IEEE_80211::kStatusCodeMaxSta] =
223 "Association denied because AP is unable to handle additional "
224 "associated STA";
225 (*status_code_string_)[IEEE_80211::kStatusCodeDataRateUnsupported] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700226 "Association denied due to requesting station not supporting all of "
227 "the data rates in the BSSBasicRateSet parameter";
Wade Guthried4977f22012-08-22 12:37:54 -0700228 (*status_code_string_)[IEEE_80211::kStatusCodeShortPreambleUnsupported] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700229 "Association denied due to requesting station not supporting the "
230 "short preamble option";
Wade Guthried4977f22012-08-22 12:37:54 -0700231 (*status_code_string_)[IEEE_80211::kStatusCodePbccUnsupported] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700232 "Association denied due to requesting station not supporting the PBCC "
233 "modulation option";
Wade Guthried4977f22012-08-22 12:37:54 -0700234 (*status_code_string_)[
235 IEEE_80211::kStatusCodeChannelAgilityUnsupported] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700236 "Association denied due to requesting station not supporting the "
237 "channel agility option";
Wade Guthried4977f22012-08-22 12:37:54 -0700238 (*status_code_string_)[IEEE_80211::kStatusCodeNeedSpectrumManagement] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700239 "Association request rejected because Spectrum Management capability "
240 "is required";
Wade Guthried4977f22012-08-22 12:37:54 -0700241 (*status_code_string_)[
242 IEEE_80211::kStatusCodeUnacceptablePowerCapability] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700243 "Association request rejected because the information in the Power "
244 "Capability element is unacceptable";
Wade Guthried4977f22012-08-22 12:37:54 -0700245 (*status_code_string_)[
246 IEEE_80211::kStatusCodeUnacceptableSupportedChannelInfo] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700247 "Association request rejected because the information in the "
248 "Supported Channels element is unacceptable";
Wade Guthried4977f22012-08-22 12:37:54 -0700249 (*status_code_string_)[IEEE_80211::kStatusCodeShortTimeSlotRequired] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700250 "Association request rejected due to requesting station not "
Wade Guthried4977f22012-08-22 12:37:54 -0700251 "supporting the Short Slot Time option";
252 (*status_code_string_)[IEEE_80211::kStatusCodeDssOfdmRequired] =
253 "Association request rejected due to requesting station not "
254 "supporting the DSSS-OFDM option";
255 (*status_code_string_)[IEEE_80211::kStatusCodeQosFailure] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700256 "Unspecified, QoS related failure";
Wade Guthried4977f22012-08-22 12:37:54 -0700257 (*status_code_string_)[
258 IEEE_80211::kStatusCodeInsufficientBandwithForQsta] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700259 "Association denied due to QAP having insufficient bandwidth to handle "
260 "another QSTA";
Wade Guthried4977f22012-08-22 12:37:54 -0700261 (*status_code_string_)[IEEE_80211::kStatusCodePoorConditions] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700262 "Association denied due to poor channel conditions";
Wade Guthried4977f22012-08-22 12:37:54 -0700263 (*status_code_string_)[IEEE_80211::kStatusCodeQosNotSupported] =
264 "Association (with QoS BSS) denied due to requesting station not "
Wade Guthrie64b4c142012-08-20 15:21:01 -0700265 "supporting the QoS facility";
Wade Guthried4977f22012-08-22 12:37:54 -0700266 (*status_code_string_)[IEEE_80211::kStatusCodeDeclined] =
267 "The request has been declined";
268 (*status_code_string_)[IEEE_80211::kStatusCodeInvalidParameterValues] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700269 "The request has not been successful as one or more parameters have "
270 "invalid values";
Wade Guthried4977f22012-08-22 12:37:54 -0700271 (*status_code_string_)[IEEE_80211::kStatusCodeCannotBeHonored] =
272 "The TS has not been created because the request cannot be honored. "
Wade Guthrie64b4c142012-08-20 15:21:01 -0700273 "However, a suggested Tspec is provided so that the initiating QSTA "
274 "may attempt to send another TS with the suggested changes to the "
275 "TSpec";
Wade Guthried4977f22012-08-22 12:37:54 -0700276 (*status_code_string_)[IEEE_80211::kStatusCodeInvalidInfoElement] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700277 "Invalid Information Element";
Wade Guthried4977f22012-08-22 12:37:54 -0700278 (*status_code_string_)[IEEE_80211::kStatusCodeGroupCipherInvalid] =
279 "Invalid Group Cipher";
280 (*status_code_string_)[IEEE_80211::kStatusCodePairwiseCipherInvalid] =
281 "Invalid Pairwise Cipher";
282 (*status_code_string_)[IEEE_80211::kStatusCodeAkmpInvalid] = "Invalid AKMP";
283 (*status_code_string_)[IEEE_80211::kStatusCodeUnsupportedRsnIeVersion] =
284 "Unsupported RSN Information Element version";
285 (*status_code_string_)[IEEE_80211::kStatusCodeInvalidRsnIeCaps] =
286 "Invalid RSN Information Element Capabilities";
287 (*status_code_string_)[IEEE_80211::kStatusCodeCipherSuiteRejected] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700288 "Cipher suite is rejected per security policy";
Wade Guthried4977f22012-08-22 12:37:54 -0700289 (*status_code_string_)[IEEE_80211::kStatusCodeTsDelayNotMet] =
290 "The TS has not been created. However, the HC may be capable of "
291 "creating a TS, in response to a request, after the time indicated in "
292 "the TS Delay element";
293 (*status_code_string_)[IEEE_80211::kStatusCodeDirectLinkIllegal] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700294 "Direct link is not allowed in the BSS by policy";
Wade Guthried4977f22012-08-22 12:37:54 -0700295 (*status_code_string_)[IEEE_80211::kStatusCodeStaNotInBss] =
296 "Destination STA is not present within this BSS";
297 (*status_code_string_)[IEEE_80211::kStatusCodeStaNotInQsta] =
298 "The destination STA is not a QoS STA";
299 (*status_code_string_)[IEEE_80211::kStatusCodeExcessiveListenInterval] =
Wade Guthrie64b4c142012-08-20 15:21:01 -0700300 "Association denied because Listen Interval is too large";
Wade Guthried4977f22012-08-22 12:37:54 -0700301 (*status_code_string_)[IEEE_80211::kStatusCodeInvalid] = "<INVALID STATUS>";
Wade Guthrie0d438532012-05-18 14:18:50 -0700302 }
303
304 return true;
305}
306
Wade Guthrie0d438532012-05-18 14:18:50 -0700307// Helper function to provide a string for a MAC address.
Wade Guthrie68da97c2013-02-26 13:09:35 -0800308bool Nl80211Message::GetMacAttributeString(int id, string *value) const {
Wade Guthrie0d438532012-05-18 14:18:50 -0700309 if (!value) {
310 LOG(ERROR) << "Null |value| parameter";
311 return false;
312 }
313
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800314 ByteString data;
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800315 if (!const_attributes()->GetRawAttributeValue(id, &data)) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700316 value->assign(kBogusMacAddress);
317 return false;
318 }
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800319 value->assign(StringFromMacAddress(data.GetConstData()));
Wade Guthrie0d438532012-05-18 14:18:50 -0700320
321 return true;
322}
323
324// Helper function to provide a string for NL80211_ATTR_SCAN_FREQUENCIES.
repo syncdc085c82012-12-28 08:54:41 -0800325bool Nl80211Message::GetScanFrequenciesAttribute(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800326 int id, vector<uint32_t> *value) const {
Wade Guthrie0d438532012-05-18 14:18:50 -0700327 if (!value) {
328 LOG(ERROR) << "Null |value| parameter";
329 return false;
330 }
331
332 value->clear();
Wade Guthried3dfd6c2013-02-28 17:40:36 -0800333
334 AttributeListConstRefPtr frequency_list;
335 if (!const_attributes()->ConstGetNestedAttributeList(
336 NL80211_ATTR_SCAN_FREQUENCIES, &frequency_list) || !frequency_list) {
337 LOG(ERROR) << "Couldn't get NL80211_ATTR_SCAN_FREQUENCIES attribute";
repo syncd316eb72012-12-10 15:48:47 -0800338 return false;
Wade Guthried3dfd6c2013-02-28 17:40:36 -0800339 }
Wade Guthrie0d438532012-05-18 14:18:50 -0700340
Wade Guthrie480aada2013-04-25 15:16:34 -0700341 AttributeIdIterator freq_iter(*frequency_list);
342 for (; !freq_iter.AtEnd(); freq_iter.Advance()) {
343 uint32_t freq = 0;
344 if (frequency_list->GetU32AttributeValue(freq_iter.GetId(), &freq)) {
345 value->push_back(freq);
346 }
Wade Guthrie0d438532012-05-18 14:18:50 -0700347 }
repo syncd316eb72012-12-10 15:48:47 -0800348 return true;
Wade Guthrie0d438532012-05-18 14:18:50 -0700349}
350
351// Helper function to provide a string for NL80211_ATTR_SCAN_SSIDS.
repo syncdc085c82012-12-28 08:54:41 -0800352bool Nl80211Message::GetScanSsidsAttribute(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800353 int id, vector<string> *value) const {
Wade Guthrie0d438532012-05-18 14:18:50 -0700354 if (!value) {
355 LOG(ERROR) << "Null |value| parameter";
356 return false;
357 }
358
Wade Guthried3dfd6c2013-02-28 17:40:36 -0800359 AttributeListConstRefPtr ssid_list;
360 if (!const_attributes()->ConstGetNestedAttributeList(
361 NL80211_ATTR_SCAN_SSIDS, &ssid_list) || !ssid_list) {
362 LOG(ERROR) << "Couldn't get NL80211_ATTR_SCAN_SSIDS attribute";
repo sync90ee0fa2012-12-18 10:08:08 -0800363 return false;
Wade Guthried3dfd6c2013-02-28 17:40:36 -0800364 }
Wade Guthrie0d438532012-05-18 14:18:50 -0700365
Wade Guthrie480aada2013-04-25 15:16:34 -0700366 AttributeIdIterator ssid_iter(*ssid_list);
367 for (; !ssid_iter.AtEnd(); ssid_iter.Advance()) {
368 string ssid;
369 if (ssid_list->GetStringAttributeValue(ssid_iter.GetId(), &ssid)) {
370 value->push_back(ssid);
371 }
Wade Guthrie0d438532012-05-18 14:18:50 -0700372 }
repo sync90ee0fa2012-12-18 10:08:08 -0800373 return true;
Wade Guthrie0d438532012-05-18 14:18:50 -0700374}
375
Wade Guthrie0d438532012-05-18 14:18:50 -0700376// static
repo syncdc085c82012-12-28 08:54:41 -0800377string Nl80211Message::StringFromMacAddress(const uint8_t *arg) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700378 string output;
379
380 if (!arg) {
381 output = kBogusMacAddress;
382 LOG(ERROR) << "|arg| parameter is NULL.";
383 } else {
384 StringAppendF(&output, "%02x", arg[0]);
385
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800386 for (unsigned int i = 1; i < kEthernetAddressBytes ; ++i) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700387 StringAppendF(&output, ":%02x", arg[i]);
388 }
389 }
390 return output;
391}
392
393// static
repo syncdc085c82012-12-28 08:54:41 -0800394string Nl80211Message::StringFromReason(uint16_t status) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700395 map<uint16_t, string>::const_iterator match;
Wade Guthried4977f22012-08-22 12:37:54 -0700396 match = reason_code_string_->find(status);
397 if (match == reason_code_string_->end()) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700398 string output;
Wade Guthried4977f22012-08-22 12:37:54 -0700399 if (status < IEEE_80211::kReasonCodeMax) {
400 StringAppendF(&output, "<Reserved Reason:%u>", status);
401 } else {
402 StringAppendF(&output, "<Unknown Reason:%u>", status);
403 }
Wade Guthrie0d438532012-05-18 14:18:50 -0700404 return output;
405 }
406 return match->second;
407}
408
Wade Guthried4977f22012-08-22 12:37:54 -0700409// static
repo syncdc085c82012-12-28 08:54:41 -0800410string Nl80211Message::StringFromStatus(uint16_t status) {
Wade Guthried4977f22012-08-22 12:37:54 -0700411 map<uint16_t, string>::const_iterator match;
412 match = status_code_string_->find(status);
413 if (match == status_code_string_->end()) {
414 string output;
415 if (status < IEEE_80211::kStatusCodeMax) {
416 StringAppendF(&output, "<Reserved Status:%u>", status);
417 } else {
418 StringAppendF(&output, "<Unknown Status:%u>", status);
419 }
420 return output;
421 }
422 return match->second;
423}
424
Wade Guthrie71872472013-03-05 10:33:38 -0800425// Nl80211Frame
426
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800427Nl80211Frame::Nl80211Frame(const ByteString &raw_frame)
Wade Guthried4977f22012-08-22 12:37:54 -0700428 : frame_type_(kIllegalFrameType), reason_(UINT16_MAX), status_(UINT16_MAX),
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800429 frame_(raw_frame) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700430 const IEEE_80211::ieee80211_frame *frame =
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800431 reinterpret_cast<const IEEE_80211::ieee80211_frame *>(
432 frame_.GetConstData());
Wade Guthrie0d438532012-05-18 14:18:50 -0700433
434 // Now, let's populate the other stuff.
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800435 if (frame_.GetLength() >= kMinimumFrameByteCount) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700436 mac_from_ =
repo syncdc085c82012-12-28 08:54:41 -0800437 Nl80211Message::StringFromMacAddress(&frame->destination_mac[0]);
438 mac_to_ = Nl80211Message::StringFromMacAddress(&frame->source_mac[0]);
Wade Guthrie0d438532012-05-18 14:18:50 -0700439 frame_type_ = frame->frame_control & kFrameTypeMask;
440
441 switch (frame_type_) {
442 case kAssocResponseFrameType:
443 case kReassocResponseFrameType:
444 status_ = le16toh(frame->u.associate_response.status_code);
445 break;
446
447 case kAuthFrameType:
448 status_ = le16toh(frame->u.authentiate_message.status_code);
449 break;
450
451 case kDisassocFrameType:
452 case kDeauthFrameType:
Wade Guthried4977f22012-08-22 12:37:54 -0700453 reason_ = le16toh(frame->u.deauthentiate_message.reason_code);
Wade Guthrie0d438532012-05-18 14:18:50 -0700454 break;
455
456 default:
457 break;
458 }
459 }
460}
461
Wade Guthried4977f22012-08-22 12:37:54 -0700462bool Nl80211Frame::ToString(string *output) const {
Wade Guthrie0d438532012-05-18 14:18:50 -0700463 if (!output) {
464 LOG(ERROR) << "NULL |output|";
465 return false;
466 }
467
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800468 if (frame_.IsEmpty()) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700469 output->append(" [no frame]");
470 return true;
471 }
472
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800473 if (frame_.GetLength() < kMinimumFrameByteCount) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700474 output->append(" [invalid frame: ");
475 } else {
476 StringAppendF(output, " %s -> %s", mac_from_.c_str(), mac_to_.c_str());
477
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800478 switch (frame_.GetConstData()[0] & kFrameTypeMask) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700479 case kAssocResponseFrameType:
480 StringAppendF(output, "; AssocResponse status: %u: %s",
481 status_,
repo syncdc085c82012-12-28 08:54:41 -0800482 Nl80211Message::StringFromStatus(status_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700483 break;
484 case kReassocResponseFrameType:
485 StringAppendF(output, "; ReassocResponse status: %u: %s",
486 status_,
repo syncdc085c82012-12-28 08:54:41 -0800487 Nl80211Message::StringFromStatus(status_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700488 break;
489 case kAuthFrameType:
490 StringAppendF(output, "; Auth status: %u: %s",
491 status_,
repo syncdc085c82012-12-28 08:54:41 -0800492 Nl80211Message::StringFromStatus(status_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700493 break;
494
495 case kDisassocFrameType:
496 StringAppendF(output, "; Disassoc reason %u: %s",
Wade Guthried4977f22012-08-22 12:37:54 -0700497 reason_,
repo syncdc085c82012-12-28 08:54:41 -0800498 Nl80211Message::StringFromReason(reason_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700499 break;
500 case kDeauthFrameType:
501 StringAppendF(output, "; Deauth reason %u: %s",
Wade Guthried4977f22012-08-22 12:37:54 -0700502 reason_,
repo syncdc085c82012-12-28 08:54:41 -0800503 Nl80211Message::StringFromReason(reason_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700504 break;
505
506 default:
507 break;
508 }
509 output->append(" [frame: ");
510 }
511
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800512 const unsigned char *frame = frame_.GetConstData();
513 for (size_t i = 0; i < frame_.GetLength(); ++i) {
514 StringAppendF(output, "%02x, ", frame[i]);
Wade Guthrie0d438532012-05-18 14:18:50 -0700515 }
516 output->append("]");
517
518 return true;
519}
520
Wade Guthried4977f22012-08-22 12:37:54 -0700521bool Nl80211Frame::IsEqual(const Nl80211Frame &other) const {
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800522 return frame_.Equals(other.frame_);
Wade Guthrie0d438532012-05-18 14:18:50 -0700523}
524
525//
repo syncdc085c82012-12-28 08:54:41 -0800526// Specific Nl80211Message types.
Wade Guthrie0d438532012-05-18 14:18:50 -0700527//
528
529const uint8_t AssociateMessage::kCommand = NL80211_CMD_ASSOCIATE;
530const char AssociateMessage::kCommandString[] = "NL80211_CMD_ASSOCIATE";
531
Wade Guthrie0d438532012-05-18 14:18:50 -0700532const uint8_t AuthenticateMessage::kCommand = NL80211_CMD_AUTHENTICATE;
533const char AuthenticateMessage::kCommandString[] = "NL80211_CMD_AUTHENTICATE";
534
Wade Guthrie0d438532012-05-18 14:18:50 -0700535const uint8_t CancelRemainOnChannelMessage::kCommand =
536 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL;
537const char CancelRemainOnChannelMessage::kCommandString[] =
538 "NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL";
539
Wade Guthrie0d438532012-05-18 14:18:50 -0700540const uint8_t ConnectMessage::kCommand = NL80211_CMD_CONNECT;
541const char ConnectMessage::kCommandString[] = "NL80211_CMD_CONNECT";
542
Wade Guthrie0d438532012-05-18 14:18:50 -0700543const uint8_t DeauthenticateMessage::kCommand = NL80211_CMD_DEAUTHENTICATE;
544const char DeauthenticateMessage::kCommandString[] =
545 "NL80211_CMD_DEAUTHENTICATE";
546
Wade Guthrie0d438532012-05-18 14:18:50 -0700547const uint8_t DeleteStationMessage::kCommand = NL80211_CMD_DEL_STATION;
548const char DeleteStationMessage::kCommandString[] = "NL80211_CMD_DEL_STATION";
549
Wade Guthrie0d438532012-05-18 14:18:50 -0700550const uint8_t DisassociateMessage::kCommand = NL80211_CMD_DISASSOCIATE;
551const char DisassociateMessage::kCommandString[] = "NL80211_CMD_DISASSOCIATE";
552
Wade Guthrie0d438532012-05-18 14:18:50 -0700553const uint8_t DisconnectMessage::kCommand = NL80211_CMD_DISCONNECT;
554const char DisconnectMessage::kCommandString[] = "NL80211_CMD_DISCONNECT";
555
Wade Guthrie0d438532012-05-18 14:18:50 -0700556const uint8_t FrameTxStatusMessage::kCommand = NL80211_CMD_FRAME_TX_STATUS;
557const char FrameTxStatusMessage::kCommandString[] =
558 "NL80211_CMD_FRAME_TX_STATUS";
559
repo sync0efa9f02012-12-28 13:40:20 -0800560const uint8_t GetRegMessage::kCommand = NL80211_CMD_GET_REG;
561const char GetRegMessage::kCommandString[] = "NL80211_CMD_GET_REG";
562
Wade Guthrie1f355e82013-04-11 15:46:12 -0700563const uint8_t GetWiphyMessage::kCommand = NL80211_CMD_GET_WIPHY;
564const char GetWiphyMessage::kCommandString[] = "NL80211_CMD_GET_WIPHY";
565
Wade Guthrie0d438532012-05-18 14:18:50 -0700566const uint8_t JoinIbssMessage::kCommand = NL80211_CMD_JOIN_IBSS;
567const char JoinIbssMessage::kCommandString[] = "NL80211_CMD_JOIN_IBSS";
568
Wade Guthrie0d438532012-05-18 14:18:50 -0700569const uint8_t MichaelMicFailureMessage::kCommand =
570 NL80211_CMD_MICHAEL_MIC_FAILURE;
571const char MichaelMicFailureMessage::kCommandString[] =
572 "NL80211_CMD_MICHAEL_MIC_FAILURE";
573
Wade Guthrie0d438532012-05-18 14:18:50 -0700574const uint8_t NewScanResultsMessage::kCommand = NL80211_CMD_NEW_SCAN_RESULTS;
575const char NewScanResultsMessage::kCommandString[] =
576 "NL80211_CMD_NEW_SCAN_RESULTS";
577
Wade Guthrie0d438532012-05-18 14:18:50 -0700578const uint8_t NewStationMessage::kCommand = NL80211_CMD_NEW_STATION;
579const char NewStationMessage::kCommandString[] = "NL80211_CMD_NEW_STATION";
580
Wade Guthrie1f355e82013-04-11 15:46:12 -0700581const uint8_t NewWiphyMessage::kCommand = NL80211_CMD_NEW_WIPHY;
582const char NewWiphyMessage::kCommandString[] = "NL80211_CMD_NEW_WIPHY";
Wade Guthrie0d438532012-05-18 14:18:50 -0700583
Wade Guthrie0d438532012-05-18 14:18:50 -0700584const uint8_t NotifyCqmMessage::kCommand = NL80211_CMD_NOTIFY_CQM;
585const char NotifyCqmMessage::kCommandString[] = "NL80211_CMD_NOTIFY_CQM";
586
Wade Guthrie0d438532012-05-18 14:18:50 -0700587const uint8_t PmksaCandidateMessage::kCommand = NL80211_ATTR_PMKSA_CANDIDATE;
588const char PmksaCandidateMessage::kCommandString[] =
589 "NL80211_ATTR_PMKSA_CANDIDATE";
590
Wade Guthrie0d438532012-05-18 14:18:50 -0700591const uint8_t RegBeaconHintMessage::kCommand = NL80211_CMD_REG_BEACON_HINT;
592const char RegBeaconHintMessage::kCommandString[] =
593 "NL80211_CMD_REG_BEACON_HINT";
594
Wade Guthrie0d438532012-05-18 14:18:50 -0700595const uint8_t RegChangeMessage::kCommand = NL80211_CMD_REG_CHANGE;
596const char RegChangeMessage::kCommandString[] = "NL80211_CMD_REG_CHANGE";
597
Wade Guthrie0d438532012-05-18 14:18:50 -0700598const uint8_t RemainOnChannelMessage::kCommand = NL80211_CMD_REMAIN_ON_CHANNEL;
599const char RemainOnChannelMessage::kCommandString[] =
600 "NL80211_CMD_REMAIN_ON_CHANNEL";
601
Wade Guthrie0d438532012-05-18 14:18:50 -0700602const uint8_t RoamMessage::kCommand = NL80211_CMD_ROAM;
603const char RoamMessage::kCommandString[] = "NL80211_CMD_ROAM";
604
Wade Guthrie0d438532012-05-18 14:18:50 -0700605const uint8_t ScanAbortedMessage::kCommand = NL80211_CMD_SCAN_ABORTED;
606const char ScanAbortedMessage::kCommandString[] = "NL80211_CMD_SCAN_ABORTED";
607
Wade Guthrie71872472013-03-05 10:33:38 -0800608const uint8_t GetScanMessage::kCommand = NL80211_CMD_GET_SCAN;
609const char GetScanMessage::kCommandString[] = "NL80211_CMD_GET_SCAN";
610
Wade Guthrie0d438532012-05-18 14:18:50 -0700611const uint8_t TriggerScanMessage::kCommand = NL80211_CMD_TRIGGER_SCAN;
612const char TriggerScanMessage::kCommandString[] = "NL80211_CMD_TRIGGER_SCAN";
613
Wade Guthrie0d438532012-05-18 14:18:50 -0700614const uint8_t UnprotDeauthenticateMessage::kCommand =
615 NL80211_CMD_UNPROT_DEAUTHENTICATE;
616const char UnprotDeauthenticateMessage::kCommandString[] =
617 "NL80211_CMD_UNPROT_DEAUTHENTICATE";
618
Wade Guthrie0d438532012-05-18 14:18:50 -0700619const uint8_t UnprotDisassociateMessage::kCommand =
620 NL80211_CMD_UNPROT_DISASSOCIATE;
621const char UnprotDisassociateMessage::kCommandString[] =
622 "NL80211_CMD_UNPROT_DISASSOCIATE";
623
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700624GetInterfaceMessage::GetInterfaceMessage()
625 : Nl80211Message(kCommand, kCommandString) {
626 attributes()->CreateAttribute(
627 NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId));
628}
629
630const uint8_t GetInterfaceMessage::kCommand = NL80211_CMD_GET_INTERFACE;
631const char GetInterfaceMessage::kCommandString[] = "NL80211_CMD_GET_INTERFACE";
632
633const uint8_t NewInterfaceMessage::kCommand = NL80211_CMD_NEW_INTERFACE;
634const char NewInterfaceMessage::kCommandString[] = "NL80211_CMD_NEW_INTERFACE";
635
Wade Guthrie12f113a2013-03-12 17:15:46 -0700636// static
637NetlinkMessage *Nl80211Message::CreateMessage(const nlmsghdr *const_msg) {
638 if (!const_msg) {
639 LOG(ERROR) << "NULL |const_msg| parameter";
640 return NULL;
641 }
642 // Casting away constness since, while nlmsg_data doesn't change its
643 // parameter, it also doesn't declare its paramenter as const.
644 nlmsghdr *msg = const_cast<nlmsghdr *>(const_msg);
645 void *payload = nlmsg_data(msg);
646 genlmsghdr *gnlh = reinterpret_cast<genlmsghdr *>(payload);
647 scoped_ptr<NetlinkMessage> message;
648
649 switch (gnlh->cmd) {
650 case AssociateMessage::kCommand:
651 return new AssociateMessage();
652 case AuthenticateMessage::kCommand:
653 return new AuthenticateMessage();
654 case CancelRemainOnChannelMessage::kCommand:
655 return new CancelRemainOnChannelMessage();
656 case ConnectMessage::kCommand:
657 return new ConnectMessage();
658 case DeauthenticateMessage::kCommand:
659 return new DeauthenticateMessage();
660 case DeleteStationMessage::kCommand:
661 return new DeleteStationMessage();
662 case DisassociateMessage::kCommand:
663 return new DisassociateMessage();
664 case DisconnectMessage::kCommand:
665 return new DisconnectMessage();
666 case FrameTxStatusMessage::kCommand:
667 return new FrameTxStatusMessage();
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700668 case GetInterfaceMessage::kCommand:
669 return new GetInterfaceMessage();
Wade Guthrie12f113a2013-03-12 17:15:46 -0700670 case GetRegMessage::kCommand:
671 return new GetRegMessage();
Wade Guthrie1f355e82013-04-11 15:46:12 -0700672 case GetWiphyMessage::kCommand:
673 return new GetWiphyMessage();
Wade Guthrie12f113a2013-03-12 17:15:46 -0700674 case JoinIbssMessage::kCommand:
675 return new JoinIbssMessage();
676 case MichaelMicFailureMessage::kCommand:
677 return new MichaelMicFailureMessage();
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700678 case NewInterfaceMessage::kCommand:
679 return new NewInterfaceMessage();
Wade Guthrie12f113a2013-03-12 17:15:46 -0700680 case NewScanResultsMessage::kCommand:
681 return new NewScanResultsMessage();
682 case NewStationMessage::kCommand:
683 return new NewStationMessage();
Wade Guthrie1f355e82013-04-11 15:46:12 -0700684 case NewWiphyMessage::kCommand:
685 return new NewWiphyMessage();
Wade Guthrie12f113a2013-03-12 17:15:46 -0700686 case NotifyCqmMessage::kCommand:
687 return new NotifyCqmMessage();
688 case PmksaCandidateMessage::kCommand:
689 return new PmksaCandidateMessage();
690 case RegBeaconHintMessage::kCommand:
691 return new RegBeaconHintMessage();
692 case RegChangeMessage::kCommand:
693 return new RegChangeMessage();
694 case RemainOnChannelMessage::kCommand:
695 return new RemainOnChannelMessage();
696 case RoamMessage::kCommand:
697 return new RoamMessage();
698 case ScanAbortedMessage::kCommand:
699 return new ScanAbortedMessage();
700 case TriggerScanMessage::kCommand:
701 return new TriggerScanMessage();
702 case UnprotDeauthenticateMessage::kCommand:
703 return new UnprotDeauthenticateMessage();
704 case UnprotDisassociateMessage::kCommand:
705 return new UnprotDisassociateMessage();
706 default:
707 LOG(WARNING) << "Unknown/unhandled netlink nl80211 message " << gnlh->cmd;
708 break;
709 }
710 return NULL;
711}
712
Wade Guthrie0d438532012-05-18 14:18:50 -0700713//
Wade Guthrie12f113a2013-03-12 17:15:46 -0700714// Data Collector
715//
716
repo syncdc085c82012-12-28 08:54:41 -0800717Nl80211MessageDataCollector *
718 Nl80211MessageDataCollector::GetInstance() {
Wade Guthrie0d438532012-05-18 14:18:50 -0700719 return g_datacollector.Pointer();
720}
721
repo syncdc085c82012-12-28 08:54:41 -0800722Nl80211MessageDataCollector::Nl80211MessageDataCollector() {
Wade Guthrie0d438532012-05-18 14:18:50 -0700723 need_to_print[NL80211_ATTR_PMKSA_CANDIDATE] = true;
724 need_to_print[NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL] = true;
725 need_to_print[NL80211_CMD_DEL_STATION] = true;
726 need_to_print[NL80211_CMD_FRAME_TX_STATUS] = true;
727 need_to_print[NL80211_CMD_JOIN_IBSS] = true;
728 need_to_print[NL80211_CMD_MICHAEL_MIC_FAILURE] = true;
729 need_to_print[NL80211_CMD_NEW_WIPHY] = true;
730 need_to_print[NL80211_CMD_REG_BEACON_HINT] = true;
731 need_to_print[NL80211_CMD_REG_CHANGE] = true;
732 need_to_print[NL80211_CMD_REMAIN_ON_CHANNEL] = true;
733 need_to_print[NL80211_CMD_ROAM] = true;
734 need_to_print[NL80211_CMD_SCAN_ABORTED] = true;
735 need_to_print[NL80211_CMD_UNPROT_DEAUTHENTICATE] = true;
736 need_to_print[NL80211_CMD_UNPROT_DISASSOCIATE] = true;
737}
738
repo syncdc085c82012-12-28 08:54:41 -0800739void Nl80211MessageDataCollector::CollectDebugData(
740 const Nl80211Message &message, nlmsghdr *msg) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700741 if (!msg) {
742 LOG(ERROR) << "NULL |msg| parameter";
743 return;
744 }
745
746 bool doit = false;
747
748 map<uint8_t, bool>::const_iterator node;
Wade Guthriebdcdaa72013-03-04 12:47:12 -0800749 node = need_to_print.find(message.command());
Wade Guthrie0d438532012-05-18 14:18:50 -0700750 if (node != need_to_print.end())
751 doit = node->second;
752
753 if (doit) {
Wade Guthried6153612012-08-23 11:36:14 -0700754 LOG(INFO) << "@@const unsigned char "
Wade Guthriebdcdaa72013-03-04 12:47:12 -0800755 << "k" << message.command_string()
Wade Guthried6153612012-08-23 11:36:14 -0700756 << "[] = {";
Wade Guthrie0d438532012-05-18 14:18:50 -0700757
Christopher Wileyefd521f2012-11-07 17:32:46 -0800758 int payload_bytes = nlmsg_datalen(msg);
Wade Guthrie0d438532012-05-18 14:18:50 -0700759
760 size_t bytes = nlmsg_total_size(payload_bytes);
761 unsigned char *rawdata = reinterpret_cast<unsigned char *>(msg);
Wade Guthried4977f22012-08-22 12:37:54 -0700762 for (size_t i = 0; i < bytes; ++i) {
Wade Guthried6153612012-08-23 11:36:14 -0700763 LOG(INFO) << " 0x"
Wade Guthrie0d438532012-05-18 14:18:50 -0700764 << std::hex << std::setfill('0') << std::setw(2)
765 << + rawdata[i] << ",";
766 }
Wade Guthried6153612012-08-23 11:36:14 -0700767 LOG(INFO) << "};";
Wade Guthriebdcdaa72013-03-04 12:47:12 -0800768 need_to_print[message.command()] = false;
Wade Guthrie0d438532012-05-18 14:18:50 -0700769 }
770}
771
772} // namespace shill.