blob: d3f4d19fbd5ba8ce9f53f9f1a8df650f6d12bb44 [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 Guthried3dfd6c2013-02-28 17:40:36 -0800341 // Assume IDs for the nested attribute array are linear starting from 1.
342 // Currently, that is enforced in the input to the nested attribute.
343 uint32_t freq;
344 int i = 1;
345 while (frequency_list->GetU32AttributeValue(i, &freq)) {
346 value->push_back(freq);
347 ++i;
Wade Guthrie0d438532012-05-18 14:18:50 -0700348 }
repo syncd316eb72012-12-10 15:48:47 -0800349 return true;
Wade Guthrie0d438532012-05-18 14:18:50 -0700350}
351
352// Helper function to provide a string for NL80211_ATTR_SCAN_SSIDS.
repo syncdc085c82012-12-28 08:54:41 -0800353bool Nl80211Message::GetScanSsidsAttribute(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800354 int id, vector<string> *value) const {
Wade Guthrie0d438532012-05-18 14:18:50 -0700355 if (!value) {
356 LOG(ERROR) << "Null |value| parameter";
357 return false;
358 }
359
Wade Guthried3dfd6c2013-02-28 17:40:36 -0800360 AttributeListConstRefPtr ssid_list;
361 if (!const_attributes()->ConstGetNestedAttributeList(
362 NL80211_ATTR_SCAN_SSIDS, &ssid_list) || !ssid_list) {
363 LOG(ERROR) << "Couldn't get NL80211_ATTR_SCAN_SSIDS attribute";
repo sync90ee0fa2012-12-18 10:08:08 -0800364 return false;
Wade Guthried3dfd6c2013-02-28 17:40:36 -0800365 }
Wade Guthrie0d438532012-05-18 14:18:50 -0700366
Wade Guthried3dfd6c2013-02-28 17:40:36 -0800367 // Assume IDs for the nested attribute array are linear starting from 1.
368 // Currently, that is enforced in the input to the nested attribute.
369 string ssid;
370 int i = 1;
371 while (ssid_list->GetStringAttributeValue(i, &ssid)) {
372 value->push_back(ssid);
373 ++i;
Wade Guthrie0d438532012-05-18 14:18:50 -0700374 }
repo sync90ee0fa2012-12-18 10:08:08 -0800375 return true;
Wade Guthrie0d438532012-05-18 14:18:50 -0700376}
377
Wade Guthrie0d438532012-05-18 14:18:50 -0700378// static
repo syncdc085c82012-12-28 08:54:41 -0800379string Nl80211Message::StringFromMacAddress(const uint8_t *arg) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700380 string output;
381
382 if (!arg) {
383 output = kBogusMacAddress;
384 LOG(ERROR) << "|arg| parameter is NULL.";
385 } else {
386 StringAppendF(&output, "%02x", arg[0]);
387
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800388 for (unsigned int i = 1; i < kEthernetAddressBytes ; ++i) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700389 StringAppendF(&output, ":%02x", arg[i]);
390 }
391 }
392 return output;
393}
394
395// static
repo syncdc085c82012-12-28 08:54:41 -0800396string Nl80211Message::StringFromReason(uint16_t status) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700397 map<uint16_t, string>::const_iterator match;
Wade Guthried4977f22012-08-22 12:37:54 -0700398 match = reason_code_string_->find(status);
399 if (match == reason_code_string_->end()) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700400 string output;
Wade Guthried4977f22012-08-22 12:37:54 -0700401 if (status < IEEE_80211::kReasonCodeMax) {
402 StringAppendF(&output, "<Reserved Reason:%u>", status);
403 } else {
404 StringAppendF(&output, "<Unknown Reason:%u>", status);
405 }
Wade Guthrie0d438532012-05-18 14:18:50 -0700406 return output;
407 }
408 return match->second;
409}
410
Wade Guthried4977f22012-08-22 12:37:54 -0700411// static
repo syncdc085c82012-12-28 08:54:41 -0800412string Nl80211Message::StringFromStatus(uint16_t status) {
Wade Guthried4977f22012-08-22 12:37:54 -0700413 map<uint16_t, string>::const_iterator match;
414 match = status_code_string_->find(status);
415 if (match == status_code_string_->end()) {
416 string output;
417 if (status < IEEE_80211::kStatusCodeMax) {
418 StringAppendF(&output, "<Reserved Status:%u>", status);
419 } else {
420 StringAppendF(&output, "<Unknown Status:%u>", status);
421 }
422 return output;
423 }
424 return match->second;
425}
426
Wade Guthrie71872472013-03-05 10:33:38 -0800427// Nl80211Frame
428
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800429Nl80211Frame::Nl80211Frame(const ByteString &raw_frame)
Wade Guthried4977f22012-08-22 12:37:54 -0700430 : frame_type_(kIllegalFrameType), reason_(UINT16_MAX), status_(UINT16_MAX),
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800431 frame_(raw_frame) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700432 const IEEE_80211::ieee80211_frame *frame =
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800433 reinterpret_cast<const IEEE_80211::ieee80211_frame *>(
434 frame_.GetConstData());
Wade Guthrie0d438532012-05-18 14:18:50 -0700435
436 // Now, let's populate the other stuff.
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800437 if (frame_.GetLength() >= kMinimumFrameByteCount) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700438 mac_from_ =
repo syncdc085c82012-12-28 08:54:41 -0800439 Nl80211Message::StringFromMacAddress(&frame->destination_mac[0]);
440 mac_to_ = Nl80211Message::StringFromMacAddress(&frame->source_mac[0]);
Wade Guthrie0d438532012-05-18 14:18:50 -0700441 frame_type_ = frame->frame_control & kFrameTypeMask;
442
443 switch (frame_type_) {
444 case kAssocResponseFrameType:
445 case kReassocResponseFrameType:
446 status_ = le16toh(frame->u.associate_response.status_code);
447 break;
448
449 case kAuthFrameType:
450 status_ = le16toh(frame->u.authentiate_message.status_code);
451 break;
452
453 case kDisassocFrameType:
454 case kDeauthFrameType:
Wade Guthried4977f22012-08-22 12:37:54 -0700455 reason_ = le16toh(frame->u.deauthentiate_message.reason_code);
Wade Guthrie0d438532012-05-18 14:18:50 -0700456 break;
457
458 default:
459 break;
460 }
461 }
462}
463
Wade Guthried4977f22012-08-22 12:37:54 -0700464bool Nl80211Frame::ToString(string *output) const {
Wade Guthrie0d438532012-05-18 14:18:50 -0700465 if (!output) {
466 LOG(ERROR) << "NULL |output|";
467 return false;
468 }
469
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800470 if (frame_.IsEmpty()) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700471 output->append(" [no frame]");
472 return true;
473 }
474
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800475 if (frame_.GetLength() < kMinimumFrameByteCount) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700476 output->append(" [invalid frame: ");
477 } else {
478 StringAppendF(output, " %s -> %s", mac_from_.c_str(), mac_to_.c_str());
479
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800480 switch (frame_.GetConstData()[0] & kFrameTypeMask) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700481 case kAssocResponseFrameType:
482 StringAppendF(output, "; AssocResponse status: %u: %s",
483 status_,
repo syncdc085c82012-12-28 08:54:41 -0800484 Nl80211Message::StringFromStatus(status_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700485 break;
486 case kReassocResponseFrameType:
487 StringAppendF(output, "; ReassocResponse status: %u: %s",
488 status_,
repo syncdc085c82012-12-28 08:54:41 -0800489 Nl80211Message::StringFromStatus(status_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700490 break;
491 case kAuthFrameType:
492 StringAppendF(output, "; Auth status: %u: %s",
493 status_,
repo syncdc085c82012-12-28 08:54:41 -0800494 Nl80211Message::StringFromStatus(status_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700495 break;
496
497 case kDisassocFrameType:
498 StringAppendF(output, "; Disassoc reason %u: %s",
Wade Guthried4977f22012-08-22 12:37:54 -0700499 reason_,
repo syncdc085c82012-12-28 08:54:41 -0800500 Nl80211Message::StringFromReason(reason_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700501 break;
502 case kDeauthFrameType:
503 StringAppendF(output, "; Deauth reason %u: %s",
Wade Guthried4977f22012-08-22 12:37:54 -0700504 reason_,
repo syncdc085c82012-12-28 08:54:41 -0800505 Nl80211Message::StringFromReason(reason_).c_str());
Wade Guthrie0d438532012-05-18 14:18:50 -0700506 break;
507
508 default:
509 break;
510 }
511 output->append(" [frame: ");
512 }
513
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800514 const unsigned char *frame = frame_.GetConstData();
515 for (size_t i = 0; i < frame_.GetLength(); ++i) {
516 StringAppendF(output, "%02x, ", frame[i]);
Wade Guthrie0d438532012-05-18 14:18:50 -0700517 }
518 output->append("]");
519
520 return true;
521}
522
Wade Guthried4977f22012-08-22 12:37:54 -0700523bool Nl80211Frame::IsEqual(const Nl80211Frame &other) const {
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800524 return frame_.Equals(other.frame_);
Wade Guthrie0d438532012-05-18 14:18:50 -0700525}
526
527//
repo syncdc085c82012-12-28 08:54:41 -0800528// Specific Nl80211Message types.
Wade Guthrie0d438532012-05-18 14:18:50 -0700529//
530
531const uint8_t AssociateMessage::kCommand = NL80211_CMD_ASSOCIATE;
532const char AssociateMessage::kCommandString[] = "NL80211_CMD_ASSOCIATE";
533
Wade Guthrie0d438532012-05-18 14:18:50 -0700534const uint8_t AuthenticateMessage::kCommand = NL80211_CMD_AUTHENTICATE;
535const char AuthenticateMessage::kCommandString[] = "NL80211_CMD_AUTHENTICATE";
536
Wade Guthrie0d438532012-05-18 14:18:50 -0700537const uint8_t CancelRemainOnChannelMessage::kCommand =
538 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL;
539const char CancelRemainOnChannelMessage::kCommandString[] =
540 "NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL";
541
Wade Guthrie0d438532012-05-18 14:18:50 -0700542const uint8_t ConnectMessage::kCommand = NL80211_CMD_CONNECT;
543const char ConnectMessage::kCommandString[] = "NL80211_CMD_CONNECT";
544
Wade Guthrie0d438532012-05-18 14:18:50 -0700545const uint8_t DeauthenticateMessage::kCommand = NL80211_CMD_DEAUTHENTICATE;
546const char DeauthenticateMessage::kCommandString[] =
547 "NL80211_CMD_DEAUTHENTICATE";
548
Wade Guthrie0d438532012-05-18 14:18:50 -0700549const uint8_t DeleteStationMessage::kCommand = NL80211_CMD_DEL_STATION;
550const char DeleteStationMessage::kCommandString[] = "NL80211_CMD_DEL_STATION";
551
Wade Guthrie0d438532012-05-18 14:18:50 -0700552const uint8_t DisassociateMessage::kCommand = NL80211_CMD_DISASSOCIATE;
553const char DisassociateMessage::kCommandString[] = "NL80211_CMD_DISASSOCIATE";
554
Wade Guthrie0d438532012-05-18 14:18:50 -0700555const uint8_t DisconnectMessage::kCommand = NL80211_CMD_DISCONNECT;
556const char DisconnectMessage::kCommandString[] = "NL80211_CMD_DISCONNECT";
557
Wade Guthrie0d438532012-05-18 14:18:50 -0700558const uint8_t FrameTxStatusMessage::kCommand = NL80211_CMD_FRAME_TX_STATUS;
559const char FrameTxStatusMessage::kCommandString[] =
560 "NL80211_CMD_FRAME_TX_STATUS";
561
repo sync0efa9f02012-12-28 13:40:20 -0800562const uint8_t GetRegMessage::kCommand = NL80211_CMD_GET_REG;
563const char GetRegMessage::kCommandString[] = "NL80211_CMD_GET_REG";
564
Wade Guthrie1f355e82013-04-11 15:46:12 -0700565const uint8_t GetWiphyMessage::kCommand = NL80211_CMD_GET_WIPHY;
566const char GetWiphyMessage::kCommandString[] = "NL80211_CMD_GET_WIPHY";
567
Wade Guthrie0d438532012-05-18 14:18:50 -0700568const uint8_t JoinIbssMessage::kCommand = NL80211_CMD_JOIN_IBSS;
569const char JoinIbssMessage::kCommandString[] = "NL80211_CMD_JOIN_IBSS";
570
Wade Guthrie0d438532012-05-18 14:18:50 -0700571const uint8_t MichaelMicFailureMessage::kCommand =
572 NL80211_CMD_MICHAEL_MIC_FAILURE;
573const char MichaelMicFailureMessage::kCommandString[] =
574 "NL80211_CMD_MICHAEL_MIC_FAILURE";
575
Wade Guthrie0d438532012-05-18 14:18:50 -0700576const uint8_t NewScanResultsMessage::kCommand = NL80211_CMD_NEW_SCAN_RESULTS;
577const char NewScanResultsMessage::kCommandString[] =
578 "NL80211_CMD_NEW_SCAN_RESULTS";
579
Wade Guthrie0d438532012-05-18 14:18:50 -0700580const uint8_t NewStationMessage::kCommand = NL80211_CMD_NEW_STATION;
581const char NewStationMessage::kCommandString[] = "NL80211_CMD_NEW_STATION";
582
Wade Guthrie1f355e82013-04-11 15:46:12 -0700583const uint8_t NewWiphyMessage::kCommand = NL80211_CMD_NEW_WIPHY;
584const char NewWiphyMessage::kCommandString[] = "NL80211_CMD_NEW_WIPHY";
Wade Guthrie0d438532012-05-18 14:18:50 -0700585
Wade Guthrie0d438532012-05-18 14:18:50 -0700586const uint8_t NotifyCqmMessage::kCommand = NL80211_CMD_NOTIFY_CQM;
587const char NotifyCqmMessage::kCommandString[] = "NL80211_CMD_NOTIFY_CQM";
588
Wade Guthrie0d438532012-05-18 14:18:50 -0700589const uint8_t PmksaCandidateMessage::kCommand = NL80211_ATTR_PMKSA_CANDIDATE;
590const char PmksaCandidateMessage::kCommandString[] =
591 "NL80211_ATTR_PMKSA_CANDIDATE";
592
Wade Guthrie0d438532012-05-18 14:18:50 -0700593const uint8_t RegBeaconHintMessage::kCommand = NL80211_CMD_REG_BEACON_HINT;
594const char RegBeaconHintMessage::kCommandString[] =
595 "NL80211_CMD_REG_BEACON_HINT";
596
Wade Guthrie0d438532012-05-18 14:18:50 -0700597const uint8_t RegChangeMessage::kCommand = NL80211_CMD_REG_CHANGE;
598const char RegChangeMessage::kCommandString[] = "NL80211_CMD_REG_CHANGE";
599
Wade Guthrie0d438532012-05-18 14:18:50 -0700600const uint8_t RemainOnChannelMessage::kCommand = NL80211_CMD_REMAIN_ON_CHANNEL;
601const char RemainOnChannelMessage::kCommandString[] =
602 "NL80211_CMD_REMAIN_ON_CHANNEL";
603
Wade Guthrie0d438532012-05-18 14:18:50 -0700604const uint8_t RoamMessage::kCommand = NL80211_CMD_ROAM;
605const char RoamMessage::kCommandString[] = "NL80211_CMD_ROAM";
606
Wade Guthrie0d438532012-05-18 14:18:50 -0700607const uint8_t ScanAbortedMessage::kCommand = NL80211_CMD_SCAN_ABORTED;
608const char ScanAbortedMessage::kCommandString[] = "NL80211_CMD_SCAN_ABORTED";
609
Wade Guthrie71872472013-03-05 10:33:38 -0800610const uint8_t GetScanMessage::kCommand = NL80211_CMD_GET_SCAN;
611const char GetScanMessage::kCommandString[] = "NL80211_CMD_GET_SCAN";
612
Wade Guthrie0d438532012-05-18 14:18:50 -0700613const uint8_t TriggerScanMessage::kCommand = NL80211_CMD_TRIGGER_SCAN;
614const char TriggerScanMessage::kCommandString[] = "NL80211_CMD_TRIGGER_SCAN";
615
Wade Guthrie0d438532012-05-18 14:18:50 -0700616const uint8_t UnprotDeauthenticateMessage::kCommand =
617 NL80211_CMD_UNPROT_DEAUTHENTICATE;
618const char UnprotDeauthenticateMessage::kCommandString[] =
619 "NL80211_CMD_UNPROT_DEAUTHENTICATE";
620
Wade Guthrie0d438532012-05-18 14:18:50 -0700621const uint8_t UnprotDisassociateMessage::kCommand =
622 NL80211_CMD_UNPROT_DISASSOCIATE;
623const char UnprotDisassociateMessage::kCommandString[] =
624 "NL80211_CMD_UNPROT_DISASSOCIATE";
625
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700626GetInterfaceMessage::GetInterfaceMessage()
627 : Nl80211Message(kCommand, kCommandString) {
628 attributes()->CreateAttribute(
629 NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId));
630}
631
632const uint8_t GetInterfaceMessage::kCommand = NL80211_CMD_GET_INTERFACE;
633const char GetInterfaceMessage::kCommandString[] = "NL80211_CMD_GET_INTERFACE";
634
635const uint8_t NewInterfaceMessage::kCommand = NL80211_CMD_NEW_INTERFACE;
636const char NewInterfaceMessage::kCommandString[] = "NL80211_CMD_NEW_INTERFACE";
637
Wade Guthrie12f113a2013-03-12 17:15:46 -0700638// static
639NetlinkMessage *Nl80211Message::CreateMessage(const nlmsghdr *const_msg) {
640 if (!const_msg) {
641 LOG(ERROR) << "NULL |const_msg| parameter";
642 return NULL;
643 }
644 // Casting away constness since, while nlmsg_data doesn't change its
645 // parameter, it also doesn't declare its paramenter as const.
646 nlmsghdr *msg = const_cast<nlmsghdr *>(const_msg);
647 void *payload = nlmsg_data(msg);
648 genlmsghdr *gnlh = reinterpret_cast<genlmsghdr *>(payload);
649 scoped_ptr<NetlinkMessage> message;
650
651 switch (gnlh->cmd) {
652 case AssociateMessage::kCommand:
653 return new AssociateMessage();
654 case AuthenticateMessage::kCommand:
655 return new AuthenticateMessage();
656 case CancelRemainOnChannelMessage::kCommand:
657 return new CancelRemainOnChannelMessage();
658 case ConnectMessage::kCommand:
659 return new ConnectMessage();
660 case DeauthenticateMessage::kCommand:
661 return new DeauthenticateMessage();
662 case DeleteStationMessage::kCommand:
663 return new DeleteStationMessage();
664 case DisassociateMessage::kCommand:
665 return new DisassociateMessage();
666 case DisconnectMessage::kCommand:
667 return new DisconnectMessage();
668 case FrameTxStatusMessage::kCommand:
669 return new FrameTxStatusMessage();
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700670 case GetInterfaceMessage::kCommand:
671 return new GetInterfaceMessage();
Wade Guthrie12f113a2013-03-12 17:15:46 -0700672 case GetRegMessage::kCommand:
673 return new GetRegMessage();
Wade Guthrie1f355e82013-04-11 15:46:12 -0700674 case GetWiphyMessage::kCommand:
675 return new GetWiphyMessage();
Wade Guthrie12f113a2013-03-12 17:15:46 -0700676 case JoinIbssMessage::kCommand:
677 return new JoinIbssMessage();
678 case MichaelMicFailureMessage::kCommand:
679 return new MichaelMicFailureMessage();
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700680 case NewInterfaceMessage::kCommand:
681 return new NewInterfaceMessage();
Wade Guthrie12f113a2013-03-12 17:15:46 -0700682 case NewScanResultsMessage::kCommand:
683 return new NewScanResultsMessage();
684 case NewStationMessage::kCommand:
685 return new NewStationMessage();
Wade Guthrie1f355e82013-04-11 15:46:12 -0700686 case NewWiphyMessage::kCommand:
687 return new NewWiphyMessage();
Wade Guthrie12f113a2013-03-12 17:15:46 -0700688 case NotifyCqmMessage::kCommand:
689 return new NotifyCqmMessage();
690 case PmksaCandidateMessage::kCommand:
691 return new PmksaCandidateMessage();
692 case RegBeaconHintMessage::kCommand:
693 return new RegBeaconHintMessage();
694 case RegChangeMessage::kCommand:
695 return new RegChangeMessage();
696 case RemainOnChannelMessage::kCommand:
697 return new RemainOnChannelMessage();
698 case RoamMessage::kCommand:
699 return new RoamMessage();
700 case ScanAbortedMessage::kCommand:
701 return new ScanAbortedMessage();
702 case TriggerScanMessage::kCommand:
703 return new TriggerScanMessage();
704 case UnprotDeauthenticateMessage::kCommand:
705 return new UnprotDeauthenticateMessage();
706 case UnprotDisassociateMessage::kCommand:
707 return new UnprotDisassociateMessage();
708 default:
709 LOG(WARNING) << "Unknown/unhandled netlink nl80211 message " << gnlh->cmd;
710 break;
711 }
712 return NULL;
713}
714
Wade Guthrie0d438532012-05-18 14:18:50 -0700715//
Wade Guthrie12f113a2013-03-12 17:15:46 -0700716// Data Collector
717//
718
repo syncdc085c82012-12-28 08:54:41 -0800719Nl80211MessageDataCollector *
720 Nl80211MessageDataCollector::GetInstance() {
Wade Guthrie0d438532012-05-18 14:18:50 -0700721 return g_datacollector.Pointer();
722}
723
repo syncdc085c82012-12-28 08:54:41 -0800724Nl80211MessageDataCollector::Nl80211MessageDataCollector() {
Wade Guthrie0d438532012-05-18 14:18:50 -0700725 need_to_print[NL80211_ATTR_PMKSA_CANDIDATE] = true;
726 need_to_print[NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL] = true;
727 need_to_print[NL80211_CMD_DEL_STATION] = true;
728 need_to_print[NL80211_CMD_FRAME_TX_STATUS] = true;
729 need_to_print[NL80211_CMD_JOIN_IBSS] = true;
730 need_to_print[NL80211_CMD_MICHAEL_MIC_FAILURE] = true;
731 need_to_print[NL80211_CMD_NEW_WIPHY] = true;
732 need_to_print[NL80211_CMD_REG_BEACON_HINT] = true;
733 need_to_print[NL80211_CMD_REG_CHANGE] = true;
734 need_to_print[NL80211_CMD_REMAIN_ON_CHANNEL] = true;
735 need_to_print[NL80211_CMD_ROAM] = true;
736 need_to_print[NL80211_CMD_SCAN_ABORTED] = true;
737 need_to_print[NL80211_CMD_UNPROT_DEAUTHENTICATE] = true;
738 need_to_print[NL80211_CMD_UNPROT_DISASSOCIATE] = true;
739}
740
repo syncdc085c82012-12-28 08:54:41 -0800741void Nl80211MessageDataCollector::CollectDebugData(
742 const Nl80211Message &message, nlmsghdr *msg) {
Wade Guthrie0d438532012-05-18 14:18:50 -0700743 if (!msg) {
744 LOG(ERROR) << "NULL |msg| parameter";
745 return;
746 }
747
748 bool doit = false;
749
750 map<uint8_t, bool>::const_iterator node;
Wade Guthriebdcdaa72013-03-04 12:47:12 -0800751 node = need_to_print.find(message.command());
Wade Guthrie0d438532012-05-18 14:18:50 -0700752 if (node != need_to_print.end())
753 doit = node->second;
754
755 if (doit) {
Wade Guthried6153612012-08-23 11:36:14 -0700756 LOG(INFO) << "@@const unsigned char "
Wade Guthriebdcdaa72013-03-04 12:47:12 -0800757 << "k" << message.command_string()
Wade Guthried6153612012-08-23 11:36:14 -0700758 << "[] = {";
Wade Guthrie0d438532012-05-18 14:18:50 -0700759
Christopher Wileyefd521f2012-11-07 17:32:46 -0800760 int payload_bytes = nlmsg_datalen(msg);
Wade Guthrie0d438532012-05-18 14:18:50 -0700761
762 size_t bytes = nlmsg_total_size(payload_bytes);
763 unsigned char *rawdata = reinterpret_cast<unsigned char *>(msg);
Wade Guthried4977f22012-08-22 12:37:54 -0700764 for (size_t i = 0; i < bytes; ++i) {
Wade Guthried6153612012-08-23 11:36:14 -0700765 LOG(INFO) << " 0x"
Wade Guthrie0d438532012-05-18 14:18:50 -0700766 << std::hex << std::setfill('0') << std::setw(2)
767 << + rawdata[i] << ",";
768 }
Wade Guthried6153612012-08-23 11:36:14 -0700769 LOG(INFO) << "};";
Wade Guthriebdcdaa72013-03-04 12:47:12 -0800770 need_to_print[message.command()] = false;
Wade Guthrie0d438532012-05-18 14:18:50 -0700771 }
772}
773
774} // namespace shill.