1// 2// Copyright (C) 2012 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16// 17// This code is derived from the 'iw' source code. The copyright and license 18// of that code is as follows: 19// 20// Copyright (c) 2007, 2008 Johannes Berg 21// Copyright (c) 2007 Andy Lutomirski 22// Copyright (c) 2007 Mike Kershaw 23// Copyright (c) 2008-2009 Luis R. Rodriguez 24// 25// Permission to use, copy, modify, and/or distribute this software for any 26// purpose with or without fee is hereby granted, provided that the above 27// copyright notice and this permission notice appear in all copies. 28// 29// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 30// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 31// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 32// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 33// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 34// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 35// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 36 37#include "shill/net/nl80211_message.h" 38 39#include <iomanip> 40#include <limits> 41#include <map> 42#include <memory> 43#include <string> 44#include <vector> 45 46#include <base/bind.h> 47#include <base/logging.h> 48#include <base/strings/stringprintf.h> 49#include <endian.h> 50 51#include "shill/net/attribute_list.h" 52#include "shill/net/ieee80211.h" 53#include "shill/net/netlink_attribute.h" 54#include "shill/net/netlink_packet.h" 55#include "shill/net/nl80211_attribute.h" // For Nl80211AttributeMac 56 57using base::Bind; 58using base::LazyInstance; 59using base::StringAppendF; 60using std::map; 61using std::string; 62using std::vector; 63 64namespace shill { 65 66namespace { 67LazyInstance<Nl80211MessageDataCollector> g_datacollector = 68 LAZY_INSTANCE_INITIALIZER; 69} // namespace 70 71const uint8_t Nl80211Frame::kMinimumFrameByteCount = 26; 72const uint8_t Nl80211Frame::kFrameTypeMask = 0xfc; 73 74const char Nl80211Message::kMessageTypeString[] = "nl80211"; 75map<uint16_t, string>* Nl80211Message::reason_code_string_ = nullptr; 76map<uint16_t, string>* Nl80211Message::status_code_string_ = nullptr; 77uint16_t Nl80211Message::nl80211_message_type_ = kIllegalMessageType; 78 79// static 80uint16_t Nl80211Message::GetMessageType() { 81 return nl80211_message_type_; 82} 83 84// static 85void Nl80211Message::SetMessageType(uint16_t message_type) { 86 if (message_type == NetlinkMessage::kIllegalMessageType) { 87 LOG(FATAL) << "Absolutely need a legal message type for Nl80211 messages."; 88 } 89 nl80211_message_type_ = message_type; 90} 91 92bool Nl80211Message::InitFromPacket(NetlinkPacket* packet, 93 NetlinkMessage::MessageContext context) { 94 if (!packet) { 95 LOG(ERROR) << "Null |packet| parameter"; 96 return false; 97 } 98 99 if (!InitAndStripHeader(packet)) { 100 return false; 101 } 102 103 return packet->ConsumeAttributes( 104 Bind(&NetlinkAttribute::NewNl80211AttributeFromId, context), attributes_); 105 106 // Convert integer values provided by the kernel (for example, from the 107 // NL80211_ATTR_STATUS_CODE or NL80211_ATTR_REASON_CODE attribute) into 108 // strings describing the status. 109 if (!reason_code_string_) { 110 reason_code_string_ = new map<uint16_t, string>; 111 (*reason_code_string_)[IEEE_80211::kReasonCodeUnspecified] = 112 "Unspecified reason"; 113 (*reason_code_string_)[ 114 IEEE_80211::kReasonCodePreviousAuthenticationInvalid] = 115 "Previous authentication no longer valid"; 116 (*reason_code_string_)[IEEE_80211::kReasonCodeSenderHasLeft] = 117 "Deauthentcated because sending STA is leaving (or has left) IBSS or " 118 "ESS"; 119 (*reason_code_string_)[IEEE_80211::kReasonCodeInactivity] = 120 "Disassociated due to inactivity"; 121 (*reason_code_string_)[IEEE_80211::kReasonCodeTooManySTAs] = 122 "Disassociated because AP is unable to handle all currently associated " 123 "STAs"; 124 (*reason_code_string_)[IEEE_80211::kReasonCodeNonAuthenticated] = 125 "Class 2 frame received from nonauthenticated STA"; 126 (*reason_code_string_)[IEEE_80211::kReasonCodeNonAssociated] = 127 "Class 3 frame received from nonassociated STA"; 128 (*reason_code_string_)[IEEE_80211::kReasonCodeDisassociatedHasLeft] = 129 "Disassociated because sending STA is leaving (or has left) BSS"; 130 (*reason_code_string_)[ 131 IEEE_80211::kReasonCodeReassociationNotAuthenticated] = 132 "STA requesting (re)association is not authenticated with responding " 133 "STA"; 134 (*reason_code_string_)[IEEE_80211::kReasonCodeUnacceptablePowerCapability] = 135 "Disassociated because the information in the Power Capability " 136 "element is unacceptable"; 137 (*reason_code_string_)[ 138 IEEE_80211::kReasonCodeUnacceptableSupportedChannelInfo] = 139 "Disassociated because the information in the Supported Channels " 140 "element is unacceptable"; 141 (*reason_code_string_)[IEEE_80211::kReasonCodeInvalidInfoElement] = 142 "Invalid information element, i.e., an information element defined in " 143 "this standard for which the content does not meet the specifications " 144 "in Clause 7"; 145 (*reason_code_string_)[IEEE_80211::kReasonCodeMICFailure] = 146 "Message integrity code (MIC) failure"; 147 (*reason_code_string_)[IEEE_80211::kReasonCode4WayTimeout] = 148 "4-Way Handshake timeout"; 149 (*reason_code_string_)[IEEE_80211::kReasonCodeGroupKeyHandshakeTimeout] = 150 "Group Key Handshake timeout"; 151 (*reason_code_string_)[IEEE_80211::kReasonCodeDifferenIE] = 152 "Information element in 4-Way Handshake different from " 153 "(Re)Association Request/Probe Response/Beacon frame"; 154 (*reason_code_string_)[IEEE_80211::kReasonCodeGroupCipherInvalid] = 155 "Invalid group cipher"; 156 (*reason_code_string_)[IEEE_80211::kReasonCodePairwiseCipherInvalid] = 157 "Invalid pairwise cipher"; 158 (*reason_code_string_)[IEEE_80211::kReasonCodeAkmpInvalid] = 159 "Invalid AKMP"; 160 (*reason_code_string_)[IEEE_80211::kReasonCodeUnsupportedRsnIeVersion] = 161 "Unsupported RSN information element version"; 162 (*reason_code_string_)[IEEE_80211::kReasonCodeInvalidRsnIeCaps] = 163 "Invalid RSN information element capabilities"; 164 (*reason_code_string_)[IEEE_80211::kReasonCode8021XAuth] = 165 "IEEE 802.1X authentication failed"; 166 (*reason_code_string_)[IEEE_80211::kReasonCodeCipherSuiteRejected] = 167 "Cipher suite rejected because of the security policy"; 168 (*reason_code_string_)[IEEE_80211::kReasonCodeUnspecifiedQoS] = 169 "Disassociated for unspecified, QoS-related reason"; 170 (*reason_code_string_)[IEEE_80211::kReasonCodeQoSBandwidth] = 171 "Disassociated because QoS AP lacks sufficient bandwidth for this " 172 "QoS STA"; 173 (*reason_code_string_)[IEEE_80211::kReasonCodeiPoorConditions] = 174 "Disassociated because excessive number of frames need to be " 175 "acknowledged, but are not acknowledged due to AP transmissions " 176 "and/or poor channel conditions"; 177 (*reason_code_string_)[IEEE_80211::kReasonCodeOutsideTxop] = 178 "Disassociated because STA is transmitting outside the limits of its " 179 "TXOPs"; 180 (*reason_code_string_)[IEEE_80211::kReasonCodeStaLeaving] = 181 "Requested from peer STA as the STA is leaving the BSS (or resetting)"; 182 (*reason_code_string_)[IEEE_80211::kReasonCodeUnacceptableMechanism] = 183 "Requested from peer STA as it does not want to use the mechanism"; 184 (*reason_code_string_)[IEEE_80211::kReasonCodeSetupRequired] = 185 "Requested from peer STA as the STA received frames using the " 186 "mechanism for which a setup is required"; 187 (*reason_code_string_)[IEEE_80211::kReasonCodeTimeout] = 188 "Requested from peer STA due to timeout"; 189 (*reason_code_string_)[IEEE_80211::kReasonCodeCipherSuiteNotSupported] = 190 "Peer STA does not support the requested cipher suite"; 191 (*reason_code_string_)[IEEE_80211::kReasonCodeInvalid] = "<INVALID REASON>"; 192 } 193 194 if (!status_code_string_) { 195 status_code_string_ = new map<uint16_t, string>; 196 (*status_code_string_)[IEEE_80211::kStatusCodeSuccessful] = "Successful"; 197 (*status_code_string_)[IEEE_80211::kStatusCodeFailure] = 198 "Unspecified failure"; 199 (*status_code_string_)[IEEE_80211::kStatusCodeAllCapabilitiesNotSupported] = 200 "Cannot support all requested capabilities in the capability " 201 "information field"; 202 (*status_code_string_)[IEEE_80211::kStatusCodeCantConfirmAssociation] = 203 "Reassociation denied due to inability to confirm that association " 204 "exists"; 205 (*status_code_string_)[IEEE_80211::kStatusCodeAssociationDenied] = 206 "Association denied due to reason outside the scope of this standard"; 207 (*status_code_string_)[ 208 IEEE_80211::kStatusCodeAuthenticationUnsupported] = 209 "Responding station does not support the specified authentication " 210 "algorithm"; 211 (*status_code_string_)[IEEE_80211::kStatusCodeOutOfSequence] = 212 "Received an authentication frame with authentication transaction " 213 "sequence number out of expected sequence"; 214 (*status_code_string_)[IEEE_80211::kStatusCodeChallengeFailure] = 215 "Authentication rejected because of challenge failure"; 216 (*status_code_string_)[IEEE_80211::kStatusCodeFrameTimeout] = 217 "Authentication rejected due to timeout waiting for next frame in " 218 "sequence"; 219 (*status_code_string_)[IEEE_80211::kStatusCodeMaxSta] = 220 "Association denied because AP is unable to handle additional " 221 "associated STA"; 222 (*status_code_string_)[IEEE_80211::kStatusCodeDataRateUnsupported] = 223 "Association denied due to requesting station not supporting all of " 224 "the data rates in the BSSBasicRateSet parameter"; 225 (*status_code_string_)[IEEE_80211::kStatusCodeShortPreambleUnsupported] = 226 "Association denied due to requesting station not supporting the " 227 "short preamble option"; 228 (*status_code_string_)[IEEE_80211::kStatusCodePbccUnsupported] = 229 "Association denied due to requesting station not supporting the PBCC " 230 "modulation option"; 231 (*status_code_string_)[ 232 IEEE_80211::kStatusCodeChannelAgilityUnsupported] = 233 "Association denied due to requesting station not supporting the " 234 "channel agility option"; 235 (*status_code_string_)[IEEE_80211::kStatusCodeNeedSpectrumManagement] = 236 "Association request rejected because Spectrum Management capability " 237 "is required"; 238 (*status_code_string_)[ 239 IEEE_80211::kStatusCodeUnacceptablePowerCapability] = 240 "Association request rejected because the information in the Power " 241 "Capability element is unacceptable"; 242 (*status_code_string_)[ 243 IEEE_80211::kStatusCodeUnacceptableSupportedChannelInfo] = 244 "Association request rejected because the information in the " 245 "Supported Channels element is unacceptable"; 246 (*status_code_string_)[IEEE_80211::kStatusCodeShortTimeSlotRequired] = 247 "Association request rejected due to requesting station not " 248 "supporting the Short Slot Time option"; 249 (*status_code_string_)[IEEE_80211::kStatusCodeDssOfdmRequired] = 250 "Association request rejected due to requesting station not " 251 "supporting the DSSS-OFDM option"; 252 (*status_code_string_)[IEEE_80211::kStatusCodeQosFailure] = 253 "Unspecified, QoS related failure"; 254 (*status_code_string_)[ 255 IEEE_80211::kStatusCodeInsufficientBandwithForQsta] = 256 "Association denied due to QAP having insufficient bandwidth to handle " 257 "another QSTA"; 258 (*status_code_string_)[IEEE_80211::kStatusCodePoorConditions] = 259 "Association denied due to poor channel conditions"; 260 (*status_code_string_)[IEEE_80211::kStatusCodeQosNotSupported] = 261 "Association (with QoS BSS) denied due to requesting station not " 262 "supporting the QoS facility"; 263 (*status_code_string_)[IEEE_80211::kStatusCodeDeclined] = 264 "The request has been declined"; 265 (*status_code_string_)[IEEE_80211::kStatusCodeInvalidParameterValues] = 266 "The request has not been successful as one or more parameters have " 267 "invalid values"; 268 (*status_code_string_)[IEEE_80211::kStatusCodeCannotBeHonored] = 269 "The TS has not been created because the request cannot be honored. " 270 "However, a suggested Tspec is provided so that the initiating QSTA " 271 "may attempt to send another TS with the suggested changes to the " 272 "TSpec"; 273 (*status_code_string_)[IEEE_80211::kStatusCodeInvalidInfoElement] = 274 "Invalid Information Element"; 275 (*status_code_string_)[IEEE_80211::kStatusCodeGroupCipherInvalid] = 276 "Invalid Group Cipher"; 277 (*status_code_string_)[IEEE_80211::kStatusCodePairwiseCipherInvalid] = 278 "Invalid Pairwise Cipher"; 279 (*status_code_string_)[IEEE_80211::kStatusCodeAkmpInvalid] = "Invalid AKMP"; 280 (*status_code_string_)[IEEE_80211::kStatusCodeUnsupportedRsnIeVersion] = 281 "Unsupported RSN Information Element version"; 282 (*status_code_string_)[IEEE_80211::kStatusCodeInvalidRsnIeCaps] = 283 "Invalid RSN Information Element Capabilities"; 284 (*status_code_string_)[IEEE_80211::kStatusCodeCipherSuiteRejected] = 285 "Cipher suite is rejected per security policy"; 286 (*status_code_string_)[IEEE_80211::kStatusCodeTsDelayNotMet] = 287 "The TS has not been created. However, the HC may be capable of " 288 "creating a TS, in response to a request, after the time indicated in " 289 "the TS Delay element"; 290 (*status_code_string_)[IEEE_80211::kStatusCodeDirectLinkIllegal] = 291 "Direct link is not allowed in the BSS by policy"; 292 (*status_code_string_)[IEEE_80211::kStatusCodeStaNotInBss] = 293 "Destination STA is not present within this BSS"; 294 (*status_code_string_)[IEEE_80211::kStatusCodeStaNotInQsta] = 295 "The destination STA is not a QoS STA"; 296 (*status_code_string_)[IEEE_80211::kStatusCodeExcessiveListenInterval] = 297 "Association denied because Listen Interval is too large"; 298 (*status_code_string_)[IEEE_80211::kStatusCodeInvalid] = "<INVALID STATUS>"; 299 } 300 301 return true; 302} 303 304// static 305string Nl80211Message::StringFromReason(uint16_t status) { 306 map<uint16_t, string>::const_iterator match; 307 match = reason_code_string_->find(status); 308 if (match == reason_code_string_->end()) { 309 string output; 310 if (status < IEEE_80211::kReasonCodeMax) { 311 StringAppendF(&output, "<Reserved Reason:%u>", status); 312 } else { 313 StringAppendF(&output, "<Unknown Reason:%u>", status); 314 } 315 return output; 316 } 317 return match->second; 318} 319 320// static 321string Nl80211Message::StringFromStatus(uint16_t status) { 322 map<uint16_t, string>::const_iterator match; 323 match = status_code_string_->find(status); 324 if (match == status_code_string_->end()) { 325 string output; 326 if (status < IEEE_80211::kStatusCodeMax) { 327 StringAppendF(&output, "<Reserved Status:%u>", status); 328 } else { 329 StringAppendF(&output, "<Unknown Status:%u>", status); 330 } 331 return output; 332 } 333 return match->second; 334} 335 336// Nl80211Frame 337 338Nl80211Frame::Nl80211Frame(const ByteString& raw_frame) 339 : frame_type_(kIllegalFrameType), 340 reason_(std::numeric_limits<uint16_t>::max()), 341 status_(std::numeric_limits<uint16_t>::max()), 342 frame_(raw_frame) { 343 const IEEE_80211::ieee80211_frame* frame = 344 reinterpret_cast<const IEEE_80211::ieee80211_frame*>( 345 frame_.GetConstData()); 346 347 // Now, let's populate the other stuff. 348 if (frame_.GetLength() >= kMinimumFrameByteCount) { 349 mac_from_ = 350 Nl80211AttributeMac::StringFromMacAddress(&frame->destination_mac[0]); 351 mac_to_ = Nl80211AttributeMac::StringFromMacAddress(&frame->source_mac[0]); 352 frame_type_ = frame->frame_control & kFrameTypeMask; 353 354 switch (frame_type_) { 355 case kAssocResponseFrameType: 356 case kReassocResponseFrameType: 357 status_ = le16toh(frame->u.associate_response.status_code); 358 break; 359 360 case kAuthFrameType: 361 status_ = le16toh(frame->u.authentiate_message.status_code); 362 break; 363 364 case kDisassocFrameType: 365 case kDeauthFrameType: 366 reason_ = le16toh(frame->u.deauthentiate_message.reason_code); 367 break; 368 369 default: 370 break; 371 } 372 } 373} 374 375bool Nl80211Frame::ToString(string* output) const { 376 if (!output) { 377 LOG(ERROR) << "NULL |output|"; 378 return false; 379 } 380 381 if (frame_.IsEmpty()) { 382 output->append(" [no frame]"); 383 return true; 384 } 385 386 if (frame_.GetLength() < kMinimumFrameByteCount) { 387 output->append(" [invalid frame: "); 388 } else { 389 StringAppendF(output, " %s -> %s", mac_from_.c_str(), mac_to_.c_str()); 390 391 switch (frame_.GetConstData()[0] & kFrameTypeMask) { 392 case kAssocResponseFrameType: 393 StringAppendF(output, "; AssocResponse status: %u: %s", 394 status_, 395 Nl80211Message::StringFromStatus(status_).c_str()); 396 break; 397 case kReassocResponseFrameType: 398 StringAppendF(output, "; ReassocResponse status: %u: %s", 399 status_, 400 Nl80211Message::StringFromStatus(status_).c_str()); 401 break; 402 case kAuthFrameType: 403 StringAppendF(output, "; Auth status: %u: %s", 404 status_, 405 Nl80211Message::StringFromStatus(status_).c_str()); 406 break; 407 408 case kDisassocFrameType: 409 StringAppendF(output, "; Disassoc reason %u: %s", 410 reason_, 411 Nl80211Message::StringFromReason(reason_).c_str()); 412 break; 413 case kDeauthFrameType: 414 StringAppendF(output, "; Deauth reason %u: %s", 415 reason_, 416 Nl80211Message::StringFromReason(reason_).c_str()); 417 break; 418 419 default: 420 break; 421 } 422 output->append(" [frame: "); 423 } 424 425 const unsigned char* frame = frame_.GetConstData(); 426 for (size_t i = 0; i < frame_.GetLength(); ++i) { 427 StringAppendF(output, "%02x, ", frame[i]); 428 } 429 output->append("]"); 430 431 return true; 432} 433 434bool Nl80211Frame::IsEqual(const Nl80211Frame& other) const { 435 return frame_.Equals(other.frame_); 436} 437 438// 439// Specific Nl80211Message types. 440// 441 442const uint8_t AssociateMessage::kCommand = NL80211_CMD_ASSOCIATE; 443const char AssociateMessage::kCommandString[] = "NL80211_CMD_ASSOCIATE"; 444 445const uint8_t AuthenticateMessage::kCommand = NL80211_CMD_AUTHENTICATE; 446const char AuthenticateMessage::kCommandString[] = "NL80211_CMD_AUTHENTICATE"; 447 448const uint8_t CancelRemainOnChannelMessage::kCommand = 449 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL; 450const char CancelRemainOnChannelMessage::kCommandString[] = 451 "NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL"; 452 453const uint8_t ConnectMessage::kCommand = NL80211_CMD_CONNECT; 454const char ConnectMessage::kCommandString[] = "NL80211_CMD_CONNECT"; 455 456const uint8_t DeauthenticateMessage::kCommand = NL80211_CMD_DEAUTHENTICATE; 457const char DeauthenticateMessage::kCommandString[] = 458 "NL80211_CMD_DEAUTHENTICATE"; 459 460const uint8_t DeleteStationMessage::kCommand = NL80211_CMD_DEL_STATION; 461const char DeleteStationMessage::kCommandString[] = "NL80211_CMD_DEL_STATION"; 462 463const uint8_t DisassociateMessage::kCommand = NL80211_CMD_DISASSOCIATE; 464const char DisassociateMessage::kCommandString[] = "NL80211_CMD_DISASSOCIATE"; 465 466const uint8_t DisconnectMessage::kCommand = NL80211_CMD_DISCONNECT; 467const char DisconnectMessage::kCommandString[] = "NL80211_CMD_DISCONNECT"; 468 469const uint8_t FrameTxStatusMessage::kCommand = NL80211_CMD_FRAME_TX_STATUS; 470const char FrameTxStatusMessage::kCommandString[] = 471 "NL80211_CMD_FRAME_TX_STATUS"; 472 473const uint8_t GetRegMessage::kCommand = NL80211_CMD_GET_REG; 474const char GetRegMessage::kCommandString[] = "NL80211_CMD_GET_REG"; 475 476const uint8_t GetStationMessage::kCommand = NL80211_CMD_GET_STATION; 477const char GetStationMessage::kCommandString[] = "NL80211_CMD_GET_STATION"; 478 479GetStationMessage::GetStationMessage() 480 : Nl80211Message(kCommand, kCommandString) { 481 attributes()->CreateAttribute( 482 NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId, 483 NetlinkMessage::MessageContext())); 484 attributes()->CreateAttribute( 485 NL80211_ATTR_MAC, Bind(&NetlinkAttribute::NewNl80211AttributeFromId, 486 NetlinkMessage::MessageContext())); 487} 488 489const uint8_t SetWakeOnPacketConnMessage::kCommand = NL80211_CMD_SET_WOWLAN; 490const char SetWakeOnPacketConnMessage::kCommandString[] = 491 "NL80211_CMD_SET_WOWLAN"; 492 493const uint8_t GetWakeOnPacketConnMessage::kCommand = NL80211_CMD_GET_WOWLAN; 494const char GetWakeOnPacketConnMessage::kCommandString[] = 495 "NL80211_CMD_GET_WOWLAN"; 496 497const uint8_t GetWiphyMessage::kCommand = NL80211_CMD_GET_WIPHY; 498const char GetWiphyMessage::kCommandString[] = "NL80211_CMD_GET_WIPHY"; 499 500GetWiphyMessage::GetWiphyMessage() : Nl80211Message(kCommand, kCommandString) { 501 attributes()->CreateAttribute( 502 NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId, 503 NetlinkMessage::MessageContext())); 504} 505 506const uint8_t JoinIbssMessage::kCommand = NL80211_CMD_JOIN_IBSS; 507const char JoinIbssMessage::kCommandString[] = "NL80211_CMD_JOIN_IBSS"; 508 509const uint8_t MichaelMicFailureMessage::kCommand = 510 NL80211_CMD_MICHAEL_MIC_FAILURE; 511const char MichaelMicFailureMessage::kCommandString[] = 512 "NL80211_CMD_MICHAEL_MIC_FAILURE"; 513 514const uint8_t NewScanResultsMessage::kCommand = NL80211_CMD_NEW_SCAN_RESULTS; 515const char NewScanResultsMessage::kCommandString[] = 516 "NL80211_CMD_NEW_SCAN_RESULTS"; 517 518const uint8_t NewStationMessage::kCommand = NL80211_CMD_NEW_STATION; 519const char NewStationMessage::kCommandString[] = "NL80211_CMD_NEW_STATION"; 520 521const uint8_t NewWiphyMessage::kCommand = NL80211_CMD_NEW_WIPHY; 522const char NewWiphyMessage::kCommandString[] = "NL80211_CMD_NEW_WIPHY"; 523 524const uint8_t NotifyCqmMessage::kCommand = NL80211_CMD_NOTIFY_CQM; 525const char NotifyCqmMessage::kCommandString[] = "NL80211_CMD_NOTIFY_CQM"; 526 527const uint8_t PmksaCandidateMessage::kCommand = NL80211_ATTR_PMKSA_CANDIDATE; 528const char PmksaCandidateMessage::kCommandString[] = 529 "NL80211_ATTR_PMKSA_CANDIDATE"; 530 531const uint8_t RegBeaconHintMessage::kCommand = NL80211_CMD_REG_BEACON_HINT; 532const char RegBeaconHintMessage::kCommandString[] = 533 "NL80211_CMD_REG_BEACON_HINT"; 534 535const uint8_t RegChangeMessage::kCommand = NL80211_CMD_REG_CHANGE; 536const char RegChangeMessage::kCommandString[] = "NL80211_CMD_REG_CHANGE"; 537 538const uint8_t RemainOnChannelMessage::kCommand = NL80211_CMD_REMAIN_ON_CHANNEL; 539const char RemainOnChannelMessage::kCommandString[] = 540 "NL80211_CMD_REMAIN_ON_CHANNEL"; 541 542const uint8_t RoamMessage::kCommand = NL80211_CMD_ROAM; 543const char RoamMessage::kCommandString[] = "NL80211_CMD_ROAM"; 544 545const uint8_t ScanAbortedMessage::kCommand = NL80211_CMD_SCAN_ABORTED; 546const char ScanAbortedMessage::kCommandString[] = "NL80211_CMD_SCAN_ABORTED"; 547 548const uint8_t GetScanMessage::kCommand = NL80211_CMD_GET_SCAN; 549const char GetScanMessage::kCommandString[] = "NL80211_CMD_GET_SCAN"; 550 551GetScanMessage::GetScanMessage() 552 : Nl80211Message(kCommand, kCommandString) { 553 attributes()->CreateAttribute( 554 NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId, 555 NetlinkMessage::MessageContext())); 556} 557 558const uint8_t TriggerScanMessage::kCommand = NL80211_CMD_TRIGGER_SCAN; 559const char TriggerScanMessage::kCommandString[] = "NL80211_CMD_TRIGGER_SCAN"; 560 561TriggerScanMessage::TriggerScanMessage() 562 : Nl80211Message(kCommand, kCommandString) { 563 attributes()->CreateAttribute( 564 NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId, 565 NetlinkMessage::MessageContext())); 566} 567 568const uint8_t UnprotDeauthenticateMessage::kCommand = 569 NL80211_CMD_UNPROT_DEAUTHENTICATE; 570const char UnprotDeauthenticateMessage::kCommandString[] = 571 "NL80211_CMD_UNPROT_DEAUTHENTICATE"; 572 573const uint8_t UnprotDisassociateMessage::kCommand = 574 NL80211_CMD_UNPROT_DISASSOCIATE; 575const char UnprotDisassociateMessage::kCommandString[] = 576 "NL80211_CMD_UNPROT_DISASSOCIATE"; 577 578GetInterfaceMessage::GetInterfaceMessage() 579 : Nl80211Message(kCommand, kCommandString) { 580 attributes()->CreateAttribute( 581 NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId, 582 NetlinkMessage::MessageContext())); 583} 584 585const uint8_t GetInterfaceMessage::kCommand = NL80211_CMD_GET_INTERFACE; 586const char GetInterfaceMessage::kCommandString[] = "NL80211_CMD_GET_INTERFACE"; 587 588const uint8_t NewInterfaceMessage::kCommand = NL80211_CMD_NEW_INTERFACE; 589const char NewInterfaceMessage::kCommandString[] = "NL80211_CMD_NEW_INTERFACE"; 590 591const uint8_t GetSurveyMessage::kCommand = NL80211_CMD_GET_SURVEY; 592const char GetSurveyMessage::kCommandString[] = "NL80211_CMD_GET_SURVEY"; 593 594GetSurveyMessage::GetSurveyMessage() 595 : Nl80211Message(kCommand, kCommandString) { 596 attributes()->CreateAttribute( 597 NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId, 598 NetlinkMessage::MessageContext())); 599 AddFlag(NLM_F_DUMP); 600} 601 602const uint8_t SurveyResultsMessage::kCommand = NL80211_CMD_NEW_SURVEY_RESULTS; 603const char SurveyResultsMessage::kCommandString[] = 604 "NL80211_CMD_NEW_SURVEY_RESULTS"; 605 606// static 607NetlinkMessage* Nl80211Message::CreateMessage(const NetlinkPacket& packet) { 608 genlmsghdr header; 609 if (!packet.GetGenlMsgHdr(&header)) { 610 LOG(ERROR) << "Could not read genl header."; 611 return nullptr; 612 } 613 std::unique_ptr<NetlinkMessage> message; 614 615 switch (header.cmd) { 616 case AssociateMessage::kCommand: 617 return new AssociateMessage(); 618 case AuthenticateMessage::kCommand: 619 return new AuthenticateMessage(); 620 case CancelRemainOnChannelMessage::kCommand: 621 return new CancelRemainOnChannelMessage(); 622 case ConnectMessage::kCommand: 623 return new ConnectMessage(); 624 case DeauthenticateMessage::kCommand: 625 return new DeauthenticateMessage(); 626 case DeleteStationMessage::kCommand: 627 return new DeleteStationMessage(); 628 case DisassociateMessage::kCommand: 629 return new DisassociateMessage(); 630 case DisconnectMessage::kCommand: 631 return new DisconnectMessage(); 632 case FrameTxStatusMessage::kCommand: 633 return new FrameTxStatusMessage(); 634 case GetInterfaceMessage::kCommand: 635 return new GetInterfaceMessage(); 636 case GetWakeOnPacketConnMessage::kCommand: 637 return new GetWakeOnPacketConnMessage(); 638 case GetRegMessage::kCommand: 639 return new GetRegMessage(); 640 case GetStationMessage::kCommand: 641 return new GetStationMessage(); 642 case GetWiphyMessage::kCommand: 643 return new GetWiphyMessage(); 644 case JoinIbssMessage::kCommand: 645 return new JoinIbssMessage(); 646 case MichaelMicFailureMessage::kCommand: 647 return new MichaelMicFailureMessage(); 648 case NewInterfaceMessage::kCommand: 649 return new NewInterfaceMessage(); 650 case NewScanResultsMessage::kCommand: 651 return new NewScanResultsMessage(); 652 case NewStationMessage::kCommand: 653 return new NewStationMessage(); 654 case NewWiphyMessage::kCommand: 655 return new NewWiphyMessage(); 656 case NotifyCqmMessage::kCommand: 657 return new NotifyCqmMessage(); 658 case PmksaCandidateMessage::kCommand: 659 return new PmksaCandidateMessage(); 660 case RegBeaconHintMessage::kCommand: 661 return new RegBeaconHintMessage(); 662 case RegChangeMessage::kCommand: 663 return new RegChangeMessage(); 664 case RemainOnChannelMessage::kCommand: 665 return new RemainOnChannelMessage(); 666 case RoamMessage::kCommand: 667 return new RoamMessage(); 668 case SetWakeOnPacketConnMessage::kCommand: 669 return new SetWakeOnPacketConnMessage(); 670 case ScanAbortedMessage::kCommand: 671 return new ScanAbortedMessage(); 672 case TriggerScanMessage::kCommand: 673 return new TriggerScanMessage(); 674 case UnprotDeauthenticateMessage::kCommand: 675 return new UnprotDeauthenticateMessage(); 676 case UnprotDisassociateMessage::kCommand: 677 return new UnprotDisassociateMessage(); 678 case GetSurveyMessage::kCommand: 679 return new GetSurveyMessage(); 680 case SurveyResultsMessage::kCommand: 681 return new SurveyResultsMessage(); 682 default: 683 LOG(WARNING) << base::StringPrintf( 684 "Unknown/unhandled netlink nl80211 message 0x%02x", header.cmd); 685 return new UnknownNl80211Message(header.cmd); 686 break; 687 } 688 return nullptr; 689} 690 691// 692// Data Collector 693// 694 695Nl80211MessageDataCollector * 696 Nl80211MessageDataCollector::GetInstance() { 697 return g_datacollector.Pointer(); 698} 699 700Nl80211MessageDataCollector::Nl80211MessageDataCollector() { 701 need_to_print[NL80211_ATTR_PMKSA_CANDIDATE] = true; 702 need_to_print[NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL] = true; 703 need_to_print[NL80211_CMD_DEL_STATION] = true; 704 need_to_print[NL80211_CMD_FRAME_TX_STATUS] = true; 705 need_to_print[NL80211_CMD_JOIN_IBSS] = true; 706 need_to_print[NL80211_CMD_MICHAEL_MIC_FAILURE] = true; 707 need_to_print[NL80211_CMD_NEW_WIPHY] = true; 708 need_to_print[NL80211_CMD_REG_BEACON_HINT] = true; 709 need_to_print[NL80211_CMD_REG_CHANGE] = true; 710 need_to_print[NL80211_CMD_REMAIN_ON_CHANNEL] = true; 711 need_to_print[NL80211_CMD_ROAM] = true; 712 need_to_print[NL80211_CMD_SCAN_ABORTED] = true; 713 need_to_print[NL80211_CMD_UNPROT_DEAUTHENTICATE] = true; 714 need_to_print[NL80211_CMD_UNPROT_DISASSOCIATE] = true; 715} 716 717void Nl80211MessageDataCollector::CollectDebugData( 718 const Nl80211Message& message, const NetlinkPacket& packet) { 719 map<uint8_t, bool>::const_iterator node; 720 node = need_to_print.find(message.command()); 721 if (node == need_to_print.end() || !node->second) 722 return; 723 724 LOG(INFO) << "@@const unsigned char " 725 << "k" << message.command_string() 726 << "[] = {"; 727 728 const unsigned char* rawdata = 729 reinterpret_cast<const unsigned char*>(&packet.GetNlMsgHeader()); 730 for (size_t i = 0; i < sizeof(nlmsghdr); ++i) { 731 LOG(INFO) << " 0x" 732 << std::hex << std::setfill('0') << std::setw(2) 733 << + rawdata[i] << ","; 734 } 735 rawdata = packet.GetPayload().GetConstData(); 736 for (size_t i = 0; i < packet.GetPayload().GetLength(); ++i) { 737 LOG(INFO) << " 0x" 738 << std::hex << std::setfill('0') << std::setw(2) 739 << + rawdata[i] << ","; 740 } 741 LOG(INFO) << "};"; 742 need_to_print[message.command()] = false; 743} 744 745} // namespace shill. 746