• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2013 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 #ifndef SHILL_NET_NETLINK_MESSAGE_MATCHERS_H_
18 #define SHILL_NET_NETLINK_MESSAGE_MATCHERS_H_
19 
20 #include <base/logging.h>
21 #include <gmock/gmock.h>
22 
23 #include "shill/net/netlink_message.h"
24 #include "shill/net/nl80211_message.h"
25 
26 namespace shill {
27 
28 // Given a netlink message, verifies that it is an Nl80211Message and verifies,
29 // further that it is the specified command.
30 MATCHER_P2(IsNl80211Command, nl80211_message_type, command, "") {
31   if (!arg) {
32     LOG(INFO) << "Null message";
33     return false;
34   }
35   if (arg->message_type() != nl80211_message_type) {
36     LOG(INFO) << "Not an nl80211 message";
37     return false;
38   }
39   const Nl80211Message* msg = static_cast<const Nl80211Message*>(arg);
40   if (msg->command() != command) {
41     LOG(INFO) << "Not a message of type " << command
42                << " (it's a " << +msg->command() << ")";
43     return false;
44   }
45   return true;
46 }
47 
48 // Given a netlink message, verifies that it is configured to disable
49 // wake on WiFi functionality of the NIC.
50 MATCHER(IsDisableWakeOnWiFiMsg, "") {
51   if (!arg) {
52     LOG(INFO) << "Null message";
53     return false;
54   }
55   const Nl80211Message* msg = static_cast<const Nl80211Message*>(arg);
56   if (msg->command() != NL80211_CMD_SET_WOWLAN) {
57     LOG(INFO) << "Not a NL80211_CMD_SET_WOWLAN message";
58     return false;
59   }
60   uint32_t wiphy;
61   if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_WIPHY,
62                                                      &wiphy)) {
63     LOG(INFO) << "Wiphy index not set";
64     return false;
65   }
66   AttributeListConstRefPtr triggers;
67   if (msg->const_attributes()->ConstGetNestedAttributeList(
68           NL80211_ATTR_WOWLAN_TRIGGERS, &triggers)) {
69     LOG(INFO) << "Message contains NL80211_ATTR_WOWLAN_TRIGGERS";
70     return false;
71   }
72   return true;
73 }
74 
75 // Verifies that a NetlinkMessage is an NL80211_CMD_TRIGGER_SCAN message that
76 // contains exactly one SSID along with the requisite empty one.
77 MATCHER_P(HasHiddenSSID, nl80211_message_type, "") {
78   if (!arg) {
79     LOG(INFO) << "Null message";
80     return false;
81   }
82   if (arg->message_type() != nl80211_message_type) {
83     LOG(INFO) << "Not an nl80211 message";
84     return false;
85   }
86   const Nl80211Message* msg = reinterpret_cast<const Nl80211Message*>(arg);
87   if (msg->command() != NL80211_CMD_TRIGGER_SCAN) {
88     LOG(INFO) << "Not a NL80211_CMD_TRIGGER_SCAN message";
89     return false;
90   }
91   AttributeListConstRefPtr ssids;
92   if (!msg->const_attributes()->ConstGetNestedAttributeList(
93       NL80211_ATTR_SCAN_SSIDS, &ssids)) {
94     LOG(INFO) << "No SSID list in message";
95     return false;
96   }
97   ByteString ssid;
98   AttributeIdIterator ssid_iter(*ssids);
99   if (!ssids->GetRawAttributeValue(ssid_iter.GetId(), &ssid)) {
100     LOG(INFO) << "SSID list contains no (hidden) SSIDs";
101     return false;
102   }
103 
104   // A valid Scan containing a single hidden SSID should contain
105   // two SSID entries: one containing the SSID we are looking for,
106   // and an empty entry, signifying that we also want to do a
107   // broadcast probe request for all non-hidden APs as well.
108   ByteString empty_ssid;
109   if (ssid_iter.AtEnd()) {
110     LOG(INFO) << "SSID list doesn't contain an empty SSIDs (but should)";
111     return false;
112   }
113   ssid_iter.Advance();
114   if (!ssids->GetRawAttributeValue(ssid_iter.GetId(), &empty_ssid) ||
115       !empty_ssid.IsEmpty()) {
116     LOG(INFO) << "SSID list doesn't contain an empty SSID (but should)";
117     return false;
118   }
119 
120   return true;
121 }
122 
123 // Verifies that a NetlinkMessage is an NL80211_CMD_TRIGGER_SCAN message that
124 // contains no SSIDs.
125 MATCHER_P(HasNoHiddenSSID, nl80211_message_type, "") {
126   if (!arg) {
127     LOG(INFO) << "Null message";
128     return false;
129   }
130   if (arg->message_type() != nl80211_message_type) {
131     LOG(INFO) << "Not an nl80211 message";
132     return false;
133   }
134   const Nl80211Message* msg = reinterpret_cast<const Nl80211Message*>(arg);
135   if (msg->command() != NL80211_CMD_TRIGGER_SCAN) {
136     LOG(INFO) << "Not a NL80211_CMD_TRIGGER_SCAN message";
137     return false;
138   }
139   AttributeListConstRefPtr ssids;
140   if (!msg->const_attributes()->ConstGetNestedAttributeList(
141       NL80211_ATTR_SCAN_SSIDS, &ssids)) {
142     return true;
143   }
144   AttributeIdIterator ssid_iter(*ssids);
145   if (ssid_iter.AtEnd()) {
146     return true;
147   }
148 
149   LOG(INFO) << "SSID list contains at least one (hidden) SSID";
150   return false;
151 }
152 
153 }  // namespace shill
154 
155 #endif  // SHILL_NET_NETLINK_MESSAGE_MATCHERS_H_
156