// // Copyright (C) 2013 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef SHILL_NET_NETLINK_MESSAGE_MATCHERS_H_ #define SHILL_NET_NETLINK_MESSAGE_MATCHERS_H_ #include <base/logging.h> #include <gmock/gmock.h> #include "shill/net/netlink_message.h" #include "shill/net/nl80211_message.h" namespace shill { // Given a netlink message, verifies that it is an Nl80211Message and verifies, // further that it is the specified command. MATCHER_P2(IsNl80211Command, nl80211_message_type, command, "") { if (!arg) { LOG(INFO) << "Null message"; return false; } if (arg->message_type() != nl80211_message_type) { LOG(INFO) << "Not an nl80211 message"; return false; } const Nl80211Message* msg = static_cast<const Nl80211Message*>(arg); if (msg->command() != command) { LOG(INFO) << "Not a message of type " << command << " (it's a " << +msg->command() << ")"; return false; } return true; } // Given a netlink message, verifies that it is configured to disable // wake on WiFi functionality of the NIC. MATCHER(IsDisableWakeOnWiFiMsg, "") { if (!arg) { LOG(INFO) << "Null message"; return false; } const Nl80211Message* msg = static_cast<const Nl80211Message*>(arg); if (msg->command() != NL80211_CMD_SET_WOWLAN) { LOG(INFO) << "Not a NL80211_CMD_SET_WOWLAN message"; return false; } uint32_t wiphy; if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_WIPHY, &wiphy)) { LOG(INFO) << "Wiphy index not set"; return false; } AttributeListConstRefPtr triggers; if (msg->const_attributes()->ConstGetNestedAttributeList( NL80211_ATTR_WOWLAN_TRIGGERS, &triggers)) { LOG(INFO) << "Message contains NL80211_ATTR_WOWLAN_TRIGGERS"; return false; } return true; } // Verifies that a NetlinkMessage is an NL80211_CMD_TRIGGER_SCAN message that // contains exactly one SSID along with the requisite empty one. MATCHER_P(HasHiddenSSID, nl80211_message_type, "") { if (!arg) { LOG(INFO) << "Null message"; return false; } if (arg->message_type() != nl80211_message_type) { LOG(INFO) << "Not an nl80211 message"; return false; } const Nl80211Message* msg = reinterpret_cast<const Nl80211Message*>(arg); if (msg->command() != NL80211_CMD_TRIGGER_SCAN) { LOG(INFO) << "Not a NL80211_CMD_TRIGGER_SCAN message"; return false; } AttributeListConstRefPtr ssids; if (!msg->const_attributes()->ConstGetNestedAttributeList( NL80211_ATTR_SCAN_SSIDS, &ssids)) { LOG(INFO) << "No SSID list in message"; return false; } ByteString ssid; AttributeIdIterator ssid_iter(*ssids); if (!ssids->GetRawAttributeValue(ssid_iter.GetId(), &ssid)) { LOG(INFO) << "SSID list contains no (hidden) SSIDs"; return false; } // A valid Scan containing a single hidden SSID should contain // two SSID entries: one containing the SSID we are looking for, // and an empty entry, signifying that we also want to do a // broadcast probe request for all non-hidden APs as well. ByteString empty_ssid; if (ssid_iter.AtEnd()) { LOG(INFO) << "SSID list doesn't contain an empty SSIDs (but should)"; return false; } ssid_iter.Advance(); if (!ssids->GetRawAttributeValue(ssid_iter.GetId(), &empty_ssid) || !empty_ssid.IsEmpty()) { LOG(INFO) << "SSID list doesn't contain an empty SSID (but should)"; return false; } return true; } // Verifies that a NetlinkMessage is an NL80211_CMD_TRIGGER_SCAN message that // contains no SSIDs. MATCHER_P(HasNoHiddenSSID, nl80211_message_type, "") { if (!arg) { LOG(INFO) << "Null message"; return false; } if (arg->message_type() != nl80211_message_type) { LOG(INFO) << "Not an nl80211 message"; return false; } const Nl80211Message* msg = reinterpret_cast<const Nl80211Message*>(arg); if (msg->command() != NL80211_CMD_TRIGGER_SCAN) { LOG(INFO) << "Not a NL80211_CMD_TRIGGER_SCAN message"; return false; } AttributeListConstRefPtr ssids; if (!msg->const_attributes()->ConstGetNestedAttributeList( NL80211_ATTR_SCAN_SSIDS, &ssids)) { return true; } AttributeIdIterator ssid_iter(*ssids); if (ssid_iter.AtEnd()) { return true; } LOG(INFO) << "SSID list contains at least one (hidden) SSID"; return false; } } // namespace shill #endif // SHILL_NET_NETLINK_MESSAGE_MATCHERS_H_